Luk*_*ron 4 scala type-inference
假设我有一张空地图
val map = Map[Int, Int]()
我很困惑,因为以下代码编译正确:
map.foldLeft((0,0)){case((k1, v1), (k2, v2)) => (-1, -1)}
Run Code Online (Sandbox Code Playgroud)
以下,看似精确的代码片段导致编译错误:
map reduceLeft {case((k1, v1), (k2, v2)) => (-1, -1)}
Run Code Online (Sandbox Code Playgroud)
错误是:
scala> map reduceLeft {case((k1, v1), (k2, v2)) => (k1, v1)}
<console>:9: error: missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: (?, (Int, Int)) => ?
map reduceLeft {case((k1, v1), (k2, v2)) => (k1, v1)}
Run Code Online (Sandbox Code Playgroud)
这不是一个大问题,但显然不必处理这个问题会很好.你对我能做些什么不同有什么想法,或者我只是必须学会接受它?
发生这种情况的原因是foldLeft有两个参数列表(第一个是初始值,"启动"值,第二个是函数)并且reduceLeft只有一个(函数).
Scala的类型推断一次运行一个参数列表.另外,在一个参数列表中推断的类型可用于在后面的那些(那些更右边)中引导或约束类型推断,其方式是它们无法帮助引导或约束给定参数列表内的类型推断.在这种情况下,Scala无法正确推断reduceLeft签名中的B类型:
def reduceLeft[B >: (A, B)](op: (B, (A, B)) ? B): B
Run Code Online (Sandbox Code Playgroud)
在折叠的情况下:
def foldLeft[B](z: B)(op: (B, (A, B)) ? B): B
Run Code Online (Sandbox Code Playgroud)
它通过单独查看您的引物值((0, 0))来将类型绑定到B,然后可以使用它来推断函数中的参数类型(不用将它们显式化).