我写了以下内容
def mapFun[T, U](xs: List[T], f: T => U): List[U] = (xs foldRight List[U]())( f(_)::_ )
Run Code Online (Sandbox Code Playgroud)
当我做的时候
def f(x: Int):Int=x*x
mapFun(List(1,2,3), f)
Run Code Online (Sandbox Code Playgroud)
它工作正常.但是,我真的想做以下工作
mapFun(List(1,2,3), x=>x*x)
Run Code Online (Sandbox Code Playgroud)
它抱怨"缺少参数类型".我知道我可以使用currying,但有没有办法仍然使用匿名函数进行上面的非currying def?
wle*_*eao 30
在我看来,因为"f"与"xs"位于相同的参数列表中,所以您需要提供有关x类型的一些信息,以便编译器可以解决它.
在你的情况下,这将工作:
mapFun(List(1,2,3) , (x: Int) => x * x)
Run Code Online (Sandbox Code Playgroud)
你看到我告诉编译器x是一个Int吗?
你可以做的一个"技巧"是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(_)::_ )
Run Code Online (Sandbox Code Playgroud)
这将工作:
mapFun(List(1,2,3))(x => x * x)
Run Code Online (Sandbox Code Playgroud)
在最后一次调用中,当编译器检查第一个参数列表时,将解析x的类型.
编辑:
正如Dominic指出的那样,你可以告诉编译器你的类型是什么.导致:
mapFun[Int, Int](List(1,2,3), x => x * x)
Run Code Online (Sandbox Code Playgroud)
干杯!
rjs*_*ean 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(_)::_ )
Run Code Online (Sandbox Code Playgroud)
类型参数T:你的第一个参数组定义(xs: List[T])为Int将提供给下一个参数组:(f: T => U).所以现在您不必T在呼叫站点明确指定.