2011-11-15 9 views
4

する機能を定義します。コードは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)) 

コンパイラは、コンパイルエラーメッセージビーイングとfilterメソッドの引数としてfを使用しようと文句を言う:

私は必要な機能の種類を満たすために、正しく機能 fを定義するにはどうすればよい
error: type mismatch; 
found : (Int, Int) => Boolean 
required: ((Int, Int)) => Boolean 

?私は(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

fFunction2[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)) 

次のように別の方法として、あなたがFunction1[Tuple2[Int, Int], Boolean]するfを再定義することができますし、それを直接使用しています。

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 

を行う場合は、その機能と同じではありません2つのintを取る関数を定義しますパラメータとして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

あなたが明示的に(missingfaktorとユーザー不明により示唆されるように)Tuple2をuseingためにあなたの機能を書き換えしたくない場合は、自動的にそれを行うには、暗黙的なメソッドを定義することができます。これにより、関数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を持つ関数について

が似なります

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) 
... 
関連する問題