Mr. Daniel Sobral已回复here Nil
fold
无法用作Nil
的初始累加器。
不能使用scala> xs
res9: List[Int] = List(1, 2, 3)
scala> xs.foldLeft(Nil)( (acc, elem) => elem.toString :: acc)
<console>:9: error: type mismatch;
found : List[String]
required: scala.collection.immutable.Nil.type
xs.foldLeft(Nil)( (acc, elem) => elem.toString :: acc)
作为初始累加器值
List[String]()
但如果我通过scala> xs.foldLeft(List[String]())( (acc, elem) => elem.toString :: acc)
res7: List[String] = List(3, 2, 1)
,它就会有用。
Nil
但为什么我可以在下面的尾递归函数中使用scala> def toStringList(as: List[Int]): List[String] = {
| def go(bs: List[Int], acc: List[String]): List[String]= bs match {
| case Nil => acc
| case x :: xs => go(xs, x.toString :: acc)
| }
| println(as)
| go(as, Nil)
| }
toStringList: (as: List[Int])List[String]
?
{{1}}
答案 0 :(得分:2)
问题是Scala使用第一个参数列表启动类型推断。给定def foldLeft[B](z: B)(f: (B, A) => B): B
和
xs.foldLeft(Nil)(...)
它将B
推断为Nil.type
(只有一个值的类型:Nil
)并使用它来键入 - 检查第二个参数列表,这显然会失败。但是,List[String]()
的类型为List[String]
,因此B
为List[String]
,这将与您的f
一起使用。另一种解决方法是显式编写类型参数:
xs.foldLeft[List[String]](Nil)(...)
在第二个程序中,给出acc
的类型(并且必须是,因为它是一个函数参数),因此不会发生与您的初始问题相对应的类型推断。