2012-06-20 2 views
4

이 질문을 호기심에서 게시하여 다음과 같은 경우 패턴 일치가 어떻게 작동하는지 알고 있습니다. 의는 다음과 같이 내가 정의 된 함수 값이 있다고 가정 해 봅시다 :스칼라 패턴 적용을 통한 부분 적용 함수

val f = (s: String) => s.toInt 

그것의 유형은 물론 문자열 => 지능이다. 이제는이 함수에 전달 된 결과물과 일치하는 패턴을 기반으로 새 함수를 만들고 싶습니다.

val f2 = f(_: String) match { 
    case i: Int => i + 2 
} 

을 이제 나의 새로운 기능은 문자열 => 지능에서도이지만, 과정이 추가 : 나는 다음과 같은 것을 정의 할 수 있습니다. 다음과 같이 호출 할 수 있습니다 : 나는 부분 응용 프로그램을하지 않고 동일한 작업을 수행하는 경우

scala> f2("3") 
res0: Int = 5 

그때는 함수 자체를 기반으로 일치를 얻을 : 이제 값 F3는 "할당 < 일치

val f3 = f match { 
    case x => "matched: " + x 
} 

function1 > "값으로 'f'와의 일치를 호출했기 때문입니다.

제 질문은 이것입니다. 스칼라가 어떻게이 두 가지를 구분합니까? 둘 다 함수 값이고 둘 다 String => Int 유형입니다. I 대전을 실행하기 전에 임시 변수 TMP에 부분적으로 적용 함수 값을 할당하는 경우 사실, 그것은 F3와 같은 동작 : 이제 F4 대신 함수가되는 할당 "<FUNCTION1> 매칭"된다

val tmp = f(_: String) 
val f4 = tmp match { 
    case x => "matched: " + x 
} 

String => Int.

나는 어느 쪽이든하고 싶은 가치를 볼 수있다, 나는 그것이 어떻게 행해졌는지 단지 궁금하다. 스칼라가 어떤 식 으로든 마법의 문맥에서 함수를 부분적으로 적용하여 다른 무언가를 생성한다는 것을 스칼라가 추측했다고 덧붙였다.

답변

9

그것은 단지 밑줄 친 방법이다.

f(_: String) match { 
    case i: Int => i + 2 
} 

(x: String) => (f(x) match { 
    case i: Int => i + 2 
}) 

위한 속기 (괄호는 일을 더 명확하게하기 위해 추가)하지만 다른 예는

(x: String => f(x)) match { 
    case y => "matched: " + y 
} 
+0

나는 확신 확실하지에 해당합니다. 두 번째 예제에서 함수 값 f는 값일 뿐이므로 x : String => f (x))를 수행 할 필요가 없습니다 ({}}. 실제로, 그것은 성냥이 행해지 기 전에 어느 곳에서든지 안으로 먹이기 위하여 가치 x가 없다. 이 경우는 type (String => Int)의 값과 일치하므로 f match {...}로 충분합니다. 나는 첫 번째 예를 산다. 이는 val tmp = (x : String) => f (x)를 의미하며, 일치로 전달됩니다. – Mike

+0

@Mike f를 η 확장 할 필요는 없지만 f는 η 확장 (x : String => f (x))과 기능적으로 동일합니다. 그는 컴파일러가 실제로 이들을 변환하는 것이 아니라, 동등하다고 말했습니다. –

+0

자, 이제 동의합니다 (x : String => f (x))는 f와 같습니다. 둘 다 String => Int입니다. 또한 f를 'f __'로 대체하여 수동 η 확장을 트리거 할 수 있음을 의미하며 f3 경우와 마찬가지로 작동해야합니다 (REPL에서 실제로 시도 했음). 그래서 이야기의 도덕적 인 부분은 일반 함수 응용 프로그램이 동일하게 동작하더라도 'f _'와 f (_ : String)는 동일하지 않다는 것입니다. – Mike