4

假设我有一张空地图
val map = Map[Int, Int]()

我很困惑,因为虽然以下代码可以正确编译:

map.foldLeft((0,0)){case((k1, v1), (k2, v2)) => (-1, -1)}

以下看似准确的代码片段会导致编译错误:

map reduceLeft {case((k1, v1), (k2, v2)) => (-1, -1)}

错误是:

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)}

这不是一个大问题,但显然不必处理这个问题会很好。你对我可以做些什么不同的想法有什么想法,还是我必须学会接受它?

4

1 回答 1

9

发生这种情况的原因是它foldLeft有两个参数列表(第一个是初始的“启动”值,第二个是函数)并且reduceLeft只有一个(函数)。

Scala 的类型推断一次操作一个参数列表。此外,在一个参数列表中推断的类型可用于指导或约束后面的(更右边的)类型推断,它们无法帮助指导或约束给定参数列表中的类型推断。在这种情况下,Scala 无法正确推断reduceLeft签名中的 B 类型:

def reduceLeft[B >: (A, B)](op: (B, (A, B)) ⇒ B): B 

在折叠情况下:

def foldLeft[B](z: B)(op: (B, (A, B)) ⇒ B): B

它通过单独查看您的初始值 ( (0, 0)) 将类型绑定到 B ,然后它可以用于推断函数中的参数类型(无需您明确说明它们)。

于 2013-02-08T01:04:38.533 回答