0

Daniel Sobral 先生在这里回答说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]
4

1 回答 1

2

问题是 Scala 从第一个参数列表开始类型推断。所以给定def foldLeft[B](z: B)(f: (B, A) => B): B

xs.foldLeft(Nil)(...)

它推断BNil.type(type which 只有一个值: Nil) 并使用它对第二个参数列表进行类型检查,这显然失败了。但是,List[String]()has 类型List[String]Bis List[String],它将与您的f. 另一种解决方法是显式编写类型参数:

xs.foldLeft[List[String]](Nil)(...)

在第二个程序中,给出了 type of acc(并且必须给出,因为它是一个函数参数),因此不会发生与您的初始问题相对应的类型推断。

于 2014-02-20T09:21:17.367 回答