我对curried和uncurried通用函数之间的类型检查的差异感到有点困惑:
scala> def x[T](a: T, b: T) = (a == b)
x: [T](a: T, b: T)Boolean
scala> def y[T](a: T)(b: T) = (a == b)
y: [T](a: T)(b: T)Boolean
Run Code Online (Sandbox Code Playgroud)
我的直觉是,这两个x(1, "one")和y(1)("one")应该给类型的错误,但是我错了:
scala> x(1, "one")
res71: Boolean = false
scala> y(1)("one")
<console>:9: error: type mismatch;
found : java.lang.String("one")
required: Int
y(1)("one")
^
Run Code Online (Sandbox Code Playgroud)
起初我以为有某种隐式演员正在进行,但事实似乎并非如此:
scala> x(1 :Int, "one" :String)
res73: Boolean = false
Run Code Online (Sandbox Code Playgroud)
发生什么了?我的直觉应该是什么?
Rex*_*err 10
Scala尝试一次确定一个参数块的类型.如果添加其他参数并部分应用,则可以看到此内容:
def x[T](a: T, b: T)(c: T) = (a == b)
scala> x(1, "one") _
res0: Any => Boolean = <function1>
Run Code Online (Sandbox Code Playgroud)
当然,这两个Int和String是Any(并且==被限定在Any).
未在早期块中使用的类型参数可以在以后的块中自由使用:
def y[T,U](a: T)(b: U)(c: (T,U)) = (a == b)
scala> y(1)("one")
res1: (Int, java.lang.String) => Boolean = <function1>
Run Code Online (Sandbox Code Playgroud)
您也可以在以后的块中使用较早的块作为默认值!
def z[T,U](a: T)(b: U)(c: (T,U) = (a,b)) = (c._1 == c._2)
scala> z(1)("one")()
res2: Boolean = false
Run Code Online (Sandbox Code Playgroud)
因此,在多个参数块之间分配参数会对类型推断和默认(以及部分应用)产生影响.
我认为在第一种情况下它是向上转换(向下转换?)两个参数,如T:Any.在第二个中,它正在为Int进行currying,然后在String上失败.
这似乎让我感到:
scala> y(1)_
res1: Int => Boolean = <function1>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
536 次 |
| 最近记录: |