为什么Scala的类型推理器无法解决此问题?

时间:2010-05-20 23:15:38

标签: scala

在下面的代码片段中 - 为什么我必须为Nil提供类型注释?

Welcome to Scala version 2.8.0.RC2 (OpenJDK Server VM, Java 1.6.0_18).
Type in expressions to have them evaluated.
Type :help for more information.

scala> List(Some(1), Some(2), Some(3), None).foldLeft(Nil)((lst, o) => o match { case Some(i) => i::lst; case None => lst })          
<console>:6: error: type mismatch;
found   : List[Int]
required: object Nil
   List(Some(1), Some(2), Some(3), None).foldLeft(Nil)((lst, o) => o match { case Some(i) => i::lst; case None => lst })
                                                                                              ^

scala> List(Some(1), Some(2), Some(3), None).foldLeft(Nil:List[Int])((lst, o) => o match { case Some(i) => i::lst; case None => lst })
res1: List[Int] = List(3, 2, 1)

2 个答案:

答案 0 :(得分:3)

问题是Nil是一个扩展List的对象。这意味着Nil.typeList的子类,因此foldLeft累加器的类型将为Nil.type

这是一个我希望Scala尝试过的地方(或者很多,无论需要什么):)更难以获得更好的类型推断。

答案 1 :(得分:0)

你可以通过这样做来避免麻烦

private def removeNone[A](xs:List[Option[A]]) = {
    xs.filter(_.isInstanceOf[Some[_]]).map(_ match {
        case Some(t) => t
        case _ => ().asInstanceOf[A] //can't happen, needed to avoid warning
    })
}

虽然这可能不会直接回答你的问题,但我在几个小时前写了这个函数,并认为这不会伤害分享它。如果您不介意收到警告,可以省略第二种情况。

我还发现地图和过滤器的组合比折叠更容易阅读。我尝试在必要时使用折叠。