의미 론적 차이는 Plasty Grove에 연결된 답변 에서 상당히 잘 설명되었습니다 .
그러나 기능면에서 큰 차이는 없습니다. 이를 확인하기 위해 몇 가지 예를 살펴 보겠습니다. 첫째, 정상적인 기능 :
scala> def modN(n: Int, x: Int): Boolean = ((x % n) == 0)
scala> modN(5, _ : Int)
res0: Int => Boolean = <function1>
그래서 우리 는 이미 첫 번째 정수를 주었기 때문에 <function1>
를 취하는 부분적으로 적용됩니다 Int
. 여태까지는 그런대로 잘됐다. 이제 카레로 :
scala> def modNCurried(n: Int)(x: Int): Boolean = ((x % n) == 0)
이 표기법을 사용하면 다음 작업이 순진하게 예상됩니다.
scala> modNCurried(5)
<console>:9: error: missing arguments for method modN;
follow this method with `_' if you want to treat it as a partially applied function
modNCurried(5)
따라서 다중 매개 변수 목록 표기법은 실제로 즉시 커리 함수를 생성하는 것처럼 보이지 않지만 (불필요한 오버 헤드를 피하기 위해) 사용자가 커리를 원한다고 명시 적으로 명시하기를 기다립니다 (표기법에는 다른 장점 도 있습니다).
scala> modNCurried(5) _
res24: Int => Boolean = <function1>
이전에 얻은 것과 똑같기 때문에 표기법을 제외하고는 차이가 없습니다. 또 다른 예:
scala> modN _
res35: (Int, Int) => Boolean = <function2>
scala> modNCurried _
res36: Int => (Int => Boolean) = <function1>
"일반"함수를 부분적으로 적용하면 모든 매개 변수를받는 함수가 생성되는 반면, 여러 매개 변수 목록이있는 함수를 부분적으로 적용하면 매개 변수 목록 당 하나씩 함수 체인이 생성 되고 모두 새 함수를 반환하는 방법을 보여줍니다.
scala> def foo(a:Int, b:Int)(x:Int)(y:Int): Int = a * b + x - y
scala> foo _
res42: (Int, Int) => Int => (Int => Int) = <function2>
scala> res42(5)
<console>:10: error: not enough arguments for method apply: (v1: Int, v2: Int)Int => (Int => Int) in trait Function2.
Unspecified value parameter v2.
보시다시피 첫 번째 매개 변수 목록 foo
에는 두 개의 매개 변수가 있으므로 커리 체인의 첫 번째 함수에는 두 개의 매개 변수가 있습니다.
요약하자면 부분적으로 적용된 함수는 기능 측면에서 실제로 다른 형태의 커리 함수가 아닙니다. 모든 함수를 카레로 변환 할 수 있다는 점을 고려하면 쉽게 확인할 수 있습니다.
scala> (modN _).curried
res45: Int => (Int => Boolean) = <function1
scala> modNCurried _
res46: Int => (Int => Boolean) = <function1>
Post Scriptum
참고 : 예제 println(filter(nums, modN(2))
가 밑줄없이 작동 하는 이유 modN(2)
는 Scala 컴파일러가 단순히 프로그래머의 편의를 위해 밑줄을 가정하기 때문인 것 같습니다.
추가 : @asflierl이 올바르게 지적했듯이 Scala는 "일반"함수를 부분적으로 적용 할 때 유형을 추론 할 수없는 것 같습니다.
scala> modN(5, _)
<console>:9: error: missing parameter type for expanded function ((x$1) => modN(5, x$1))
이 정보는 다중 매개 변수 목록 표기법을 사용하여 작성된 함수에 사용할 수 있습니다.
scala> modNCurried(5) _
res3: Int => Boolean = <function1>
이 답변 은 이것이 얼마나 유용 할 수 있는지 보여줍니다.