2011-11-15 2 views
4

저는 스칼라 코드로 놀아 왔고, 이해하지 못하는 컴파일러 에러에 대해서 제기했습니다. 이 코드는 Ints 쌍의 벡터를 생성 한 다음이를 필터링하려고 시도합니다. 정확하게 필요한 기능 유형을 만족시키기 위해 내가 기능 f를 정의하려면 어떻게스칼라 : 함수를 올바른 타입으로 정의하기

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

:

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을 사용하려고 뿌려 ? 나는 (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]]이므로 filterFunction1[Tuple2[Int, Int], Boolean] 유형의 기능을 기대합니다. FunctionN[A, B, .., R] 특성은 tupled 메서드를 가지고 있으며 Function1[TupleN[A, B, ..], R] 형식의 함수를 반환합니다. 여기서 fL.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 

당신이 함수와 동일하지 않습니다 두 가지의 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을 재 작성하지 않으려면, 당신은 자동으로 할 수있는 암시 적 방법을 정의 할 수 있습니다. 이렇게하면 함수 x가 여전히 식별자 x와 y를 사용하기 때문에 함수 f를 그대로 유지할 수 있습니다 (사용자는 항상 Tuple2 매개 변수로 호출해야합니다). 이해하기 쉽습니다.

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로 사용될 수있다. 두 개 이상의 매개 변수를 암시 인증 된 정의와 함수의

는 비슷한 같습니다

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) 
... 
관련 문제