jmo*_*unt 5 scala type-parameter
我有一些Scala代码,它使用两个不同版本的类型参数化函数做了一些很好的事情.我从我的应用程序,但最终我的代码完全形式的通话简化这个了很多w(f[Int],f[Double])地方w()是我的魔术方法.我希望有一个更神奇的方法z(f) = w(f[Int],f[Double])- 但我不能得到任何语法z(f[Z]:Z->Z),因为它看起来(对我来说)函数参数不能有自己的类型参数.这是Scala代码段的问题.
有任何想法吗?宏可以做到,但我不认为那些是Scala的一部分.
object TypeExample {
def main(args: Array[String]):Unit = {
def f[X](x:X):X = x // parameterize fn
def v(f:Int=>Int):Unit = { } // function that operates on an Int to Int function
v(f) // applied, types correct
v(f[Int]) // appplied, types correct
def w[Z](f:Z=>Z,g:Double=>Double):Unit = {} // function that operates on two functions
w(f[Int],f[Double]) // works
// want something like this: def z[Z](f[Z]:Z=>Z) = w(f[Int],f[Double])
// a type parameterized function that takes a single type-parameterized function as an
// argument and then speicalizes the the argument-function to two different types,
// i.e. a single-argument version of w() (or wrapper)
}
}
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
trait Forall {
def f[Z] : Z=>Z
}
def z(u : Forall) = w(u.f[Int], u.f[Double])
Run Code Online (Sandbox Code Playgroud)
或者使用结构类型:
def z(u : {def f[Z] : Z=>Z}) = w(u.f[Int], u.f[Double])
Run Code Online (Sandbox Code Playgroud)
但这比第一个版本慢,因为它使用反射.
编辑:这是你如何使用第二个版本:
scala> object f1 {def f[Z] : Z=>Z = x => x}
defined module f1
scala> def z(u : {def f[Z] : Z=>Z}) = (u.f[Int](0), u.f[Double](0.0))
z: (AnyRef{def f[Z]: (Z) => Z})(Int, Double)
scala> z(f1)
res0: (Int, Double) = (0,0.0)
Run Code Online (Sandbox Code Playgroud)
对于第一个版本添加f1 extends Forall或简单
scala> z(new Forall{def f[Z] : Z=>Z = x => x})
Run Code Online (Sandbox Code Playgroud)
如果你很好奇,你在这里谈论的是"rank-k多态".见维基百科.在你的情况下,k = 2.一些翻译:
当你写作
f[X](x : X) : X = ...
Run Code Online (Sandbox Code Playgroud)
然后你说f的类型为"forall XX - > X"
你想要的z是"(forall ZZ - > Z) - >单位".额外的一对括号是一个很大的区别.就维基百科文章而言,它将forall限定符放在2个箭头而不是1个之前.类型变量不能仅实例化一次并且可以执行,它可能必须实例化为许多不同类型.(这里"实例化"并不意味着对象构造,它意味着将类型赋给类型变量以进行类型检查).
正如alexy_r的回答所示,这可以使用对象而不是直接函数类型在Scala中编码,基本上使用类/特征作为parens.虽然他似乎让你在插入原始代码方面有点悬而未决,所以这里是:
//这是你的代码
object TypeExample {
def main(args: Array[String]):Unit = {
def f[X](x:X):X = x // parameterize fn
def v(f:Int=>Int):Unit = { } // function that operates on an Int to Int function
v(f) // applied, types correct
v(f[Int]) // appplied, types correct
def w[Z](f:Z=>Z,g:Double=>Double):Unit = {} // function that operates on two functions
w(f[Int],f[Double]) // works
Run Code Online (Sandbox Code Playgroud)
//这是新代码
trait ForAll {
def g[X](x : X) : X
}
def z(forall : ForAll) = w(forall.g[Int], forall.g[Double])
z(new ForAll{def g[X](x : X) = f(x)})
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3823 次 |
| 最近记录: |