5

我试图反转整数列表,如下所示:

List(1,2,3,4).foldLeft(List[Int]()){(a,b) => b::a}

我的问题是,有没有办法将种子指定为scalaList[_]_类型推断机制自动填充的类型,而不必将类型指定为List[Int]?

谢谢

4

2 回答 2

5

更新:在阅读了有关 Scala 类型推断的更多内容后,我找到了更好的答案来回答您的问题。这篇关于 Scala 类型推断限制的文章说:

Scala 中的类型信息从函数参数流向它们的结果 [...],从左到右跨参数列表,从第一个到最后一个跨语句。这与具有完整类型推断的语言形成对比,其中(粗略地说)类型信息在各个方向上不受限制地流动。

所以问题是 Scala 的类型推断是相当有限的。它首先查看第一个参数列表(您的案例中的列表),然后查看第二个参数列表(函数)。但它不会回去。

这就是为什么这

List(1,2,3,4).foldLeft(Nil){(a,b) => b::a}

也不是这个

List(1,2,3,4).foldLeft(List()){(a,b) => b::a}

将工作。为什么?首先,签名的foldLeft定义为:

 foldLeft[B](z: B)(f: (B, A) => B): B 

所以如果你Nil作为第一个参数使用z,编译器会分配Nil.type给类型参数B。如果您使用List(),编译器将使用List[Nothing]for B

现在,第二个参数的类型f已完全定义。在你的情况下,它要么

(Nil.type, Int) => Nil.type

或者

(List[Nothing], Int) => List[Nothing]

在这两种情况下,lambda 表达式(a, b) => b :: a都是无效的,因为它的返回类型被推断为List[Int].


请注意,上面的粗体部分表示“参数列表”而不是“参数”。文章稍后解释:

类型信息不会在参数列表中从左到右流动只会在参数列表中从左到右流动。

因此,如果您有一个带有单个参数列表的方法,情况会更糟。

于 2012-11-21T07:54:56.147 回答
4

我知道的唯一方法是

scala> def foldList[T](l: List[T]) = l.foldLeft(List[T]()){(a,b) => b::a}
foldList: [T](l: List[T])List[T]

scala> foldList(List(1,2,3,4))
res19: List[Int] = List(4, 3, 2, 1)

scala> foldList(List("a","b","c"))
res20: List[java.lang.String] = List(c, b, a)
于 2012-11-21T06:58:49.697 回答