【发布时间】:2012-04-04 20:27:28
【问题描述】:
当我使用 foldLeft 构建列表时,我经常对必须显式键入注入的参数感到恼火,并希望我可以只使用 `Nil' 代替 - 这是一个人为的示例:
scala> List(1,2,3).foldLeft(List[Int]())((x,y) => y :: x)
res17: List[Int] = List(3, 2, 1)
scala> List(1,2,3).foldLeft(Nil)((x, y) => y :: x)
<console>:10: error: type mismatch;
found : List[Int]
required: scala.collection.immutable.Nil.type
List(1,2,3).foldLeft(Nil)((x,y) => y :: x)
List[Int] 并没有那么糟糕,但是一旦你开始使用你自己的类的列表,它们几乎肯定会有更长的名称,甚至是元组或其他容器的列表,所以有多个你需要指定的类名,它变得可怕:
list.foldLeft(List.empty[(SomethingClass, SomethingElseClass)]) { (x,y) => y :: x }
我猜它不起作用的原因是,虽然使用5 :: Nil 之类的东西,编译器可以推断出空列表的类型为List[Int],但是当Nil 作为参数传递时对于foldLeft,它没有足够的信息来执行此操作,并且当它被使用时,它的类型已设置。但是 - 它真的不能吗?它不能从作为第二个参数传递的函数的返回类型推断类型吗?
如果没有,是否有一些我不知道的更简洁的成语?
【问题讨论】:
-
遗憾的是,Scala 无法推断出这种情况的类型。让我们希望将来会对此进行修改。
-
在实践中应该问题不大。如果您只是处理一些特定的类,请在顶部
type S = (SomethingClass, SomethingElseClass)或val nil = List.empty[(SomethingClass, SomethingElseClass)]处创建一个类型别名。如果您正在编写泛型方法,则您的类型将已经有短别名,例如T和U。
标签: scala type-inference fold