2011-11-15 72 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) 
... 
相關問題