我写了以下
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?
答案 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
。