2011-11-15 30 views
4

我一直在玩Scala代码,并遇到了一个编译器错误,我不明白。该代码生成一对Ints对的向量,然后尝试对其进行过滤。Scala:定义一个函数是正确的类型

val L = for (x <- (1 to 5)) yield (x, x * x) 
val f = (x: Int, y: Int) => x > 3 
println(L.filter(f)) 

编译器抱怨试图用f作为参数为filter方法与编译器错误消息是:

error: type mismatch; 
found : (Int, Int) => Boolean 
required: ((Int, Int)) => Boolean 

如何定义功能f正确,以满足所需的功能类型?我尝试添加周围(x: Int, y: Int)额外的括号,但是这给了:

error: not a legal formal parameter 
    val f = ((x: Int, y: Int)) => x > 3 
      ^
+1

这个问题是去除参数列表和元组之间的区别的争论。也就是说,现在,'f(x,y)'中的'(x,y)'是一种与裸露的'(x,y)'本身不同的东西。不幸的是,消除这种区别在技术上并不重要。 –

回答

13

f具有类型Function2[Int, Int, Boolean]L的类型为IndexedSeq[Tuple2[Int, Int]],因此filter需要Function1[Tuple2[Int, Int], Boolean]类型的函数。每个FunctionN[A, B, .., R]特征都有一个方法tupled,它返回Function1[TupleN[A, B, ..], R]类型的函数。您可以在此处使用它将f转换为L.filter预期的类型。

println(L.filter(f.tupled)) 
> Vector((4,16), (5,25)) 

或者,也可以重新定义f是一个Function1[Tuple2[Int, Int], Boolean]如下和直接使用它。

val f = (t: (Int, Int)) => t._1 > 3 
println(L.filter(f)) 
> Vector((4,16), (5,25)) 
6
val f = (xy: (Int, Int)) => xy._1 > 3 
println (L.filter (f)) 

如果你

val f = (x: Int, y: Int) => x > 3 

你定义一个函数,它接受两个整数,这是不一样的功能,以一对int作为参数。

比较:

scala> val f = (x: Int, y: Int) => x > 3 
f: (Int, Int) => Boolean = <function2> 

scala> val f = (xy: (Int, Int)) => xy._1 > 3 
f: ((Int, Int)) => Boolean = <function1> 
0

如果您不希望重写功能明确地期运用Tuple2(由missingfaktor和用户未知的建议),你可以定义自动做一个隐式方法。这可以让函数f保持不变(您不必总是使用Tuple2参数调用它)并且更容易理解,因为您仍然使用标识符x和y。

implicit def fun2ToTuple[A,B,Res](f:(A,B)=>Res):((A,B))=>Res = 
    (t:(A,B)) => f(t._1, t._2) 
val L = for (x <- (1 to 5)) yield (x, x * x) 
val f = (x: Int, y: Int) => x > 3 
val g = (x: Int, y: Int) => x % 2 > y % 3 
L.filter(f) //> Vector((4,16), (5,25)) 
L.filter(g) //> Vector((3,9)) 
f(0,1)   //> false 
f((4,2))  //> true 

现在每个功能2也可以作为与Tuple2一个功能1的参数,因为它采用了隐式方法,如果需要的功能转换。

对于具有两个以上参数的隐含DEFS功能看起来similiar:

implicit def fun3ToTuple[A,B,C,Res](f:(A,B,C)=>Res):((A,B,C))=>Res = 
    (t:(A,B,C)) => f(t._1, t._2, t._3) 
implicit def fun4ToTuple[A,B,C,D,Res](f:(A,B,C,D)=>Res):((A,B,C,D))=>Res = 
    (t:(A,B,C,D)) => f(t._1, t._2, t._3, t._4) 
... 
相关问题