scala匿名函数缺少参数类型错误

时间:2012-10-29 02:01:55

标签: scala

我写了以下

def mapFun[T, U](xs: List[T], f: T => U): List[U] = (xs foldRight List[U]())( f(_)::_ )

当我做的时候

def f(x: Int):Int=x*x
mapFun(List(1,2,3), f)

工作得很好。但是,我真的很想做以下工作

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

它抱怨“缺少参数类型”。我知道我可以使用currying,但有没有办法仍然使用匿名函数进行上面的非currying def?

2 个答案:

答案 0 :(得分:28)

在我看来,因为" f"与" xs"在同一参数列表中,您需要提供有关x类型的一些信息,以便编译器可以解决它。

在您的情况下,这将有效:

mapFun(List(1,2,3) , (x: Int) => x * x)  

您是否了解我如何通知编译器x是Int?

A"技巧"你能做的就是讨好f。如果你不知道什么是currying,请查看:http://www.codecommit.com/blog/scala/function-currying-in-scala

你最终会得到这样的mapFun:

def mapFun[T, U](xs: List[T])(f: T => U): List[U] = 
    (xs foldRight List[U]())( f(_)::_ )

这将有效:

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

在最后一次调用中,当编译器检查第一个参数列表时,将解析x的类型。

修改

正如多米尼克指出的那样,你可以告诉编译器你的类型是什么。导致:

mapFun[Int, Int](List(1,2,3), x => x * x)

干杯!

答案 1 :(得分:16)

您在此处遇到的scala类型系统的限制是,类型信息在参数组中从左向右流动 ,并且在参数内不会从左向右流动即可。

这意味着通过提供T来指定类型参数List[Int]不会将该信息提供给组内的其他参数,例如f。这导致缺少参数类型错误。但如果f是下一个参数组的一部分,它将提供给f。这就是curry函数方法的工作原理。

即。如果你这样定义:

def mapFun[T, U](xs: List[T])(f: T => U): List[U] = (xs foldRight List[U]())( f(_)::_ )

您在第一个参数组中定义的类型参数T(xs: List[T])作为Int将可用于下一个参数组:(f: T => U)。所以现在您不必在呼叫站点明确指定T