我试图反转整数列表,如下所示:
List(1,2,3,4).foldLeft(List[Int]()){(a,b) => b::a}
我的问题是,有没有办法将种子指定为scalaList[_]
的_
类型推断机制自动填充的类型,而不必将类型指定为List[Int]
?
谢谢
我试图反转整数列表,如下所示:
List(1,2,3,4).foldLeft(List[Int]()){(a,b) => b::a}
我的问题是,有没有办法将种子指定为scalaList[_]
的_
类型推断机制自动填充的类型,而不必将类型指定为List[Int]
?
谢谢
更新:在阅读了有关 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]
.
请注意,上面的粗体部分表示“参数列表”而不是“参数”。文章稍后解释:
类型信息不会在参数列表中从左到右流动,只会在参数列表中从左到右流动。
因此,如果您有一个带有单个参数列表的方法,情况会更糟。
我知道的唯一方法是
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)