关于scala类型推断的编译错误

用户名

我正在做一个简单的练习,要求我使用foldRight在列表上实现独立的“地图”功能。我想出的解决方案是:

def mapFun[T,U](xs: List[T], f: T => U): List[U] = {
  (xs foldRight List[U]())((x, y) => f(x) :: y)
}

val sl = List(1,2,3)

//now try to square every item
mapFun(sl, x => x * x)  //**missing parameter type**
mapFun(sl, (x:Int) => x * x) //ok, gives List(1,4,9)

如上所述,必须指定一个显式的“ Int”类型才能编译代码。但是在我看来,编译器应该能够推断“ x”的类型,因为“ sl”的类型为“ List [Int]”,这意味着T为“ Int”,然后“ x * x”表达式的类型为U也应为“ Int”。

我想这可能与方差或逆方差有关,或者子类型与通用类型混合在一起。

我的Scala编译器版本为2.11 bundle(动态)。


标准答案的补充:来自Scala的函数编程,第3章:

这是Scala编译器的不幸限制。其他功能语言(例如Haskell和OCaml)提供完整的推断,这意味着几乎不需要类型标注

尤瓦尔·伊茨恰科夫(Yuval Itzchakov)

Scala的类型推断不会在参数列表内部流动,而只会在参数列表之间流动这将起作用:

def mapFun[T,U](xs: List[T])(f: T => U): List[U] = {
  (xs foldRight List[U]())((x, y) => f(x) :: y)
}

val sl = List(1,2,3)
println(mapFun(sl)(x => x * x))

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章