파라미터 언튜플링
파라미터 언튜플링 (Parameter Untupling)
짝(pair)들의 리스트에서 각 요소를 풀어서 처리하고 싶을 때, 예전에는 패턴 매칭으로 분해해야만 했어요. Scala 3부터는 함수 값에 튜플로 묶인 파라미터를 자동으로 풀어 넘겨주는 '파라미터 언튜플링'이 지원돼서 훨씬 간결하게 쓸 수 있습니다.
본문
짝들의 리스트가 있다고 해 볼게요.
val xs: List[(Int, Int)]
xs를 각 짝이 숫자들의 합으로 매핑된 Int 리스트로 바꾸고 싶다고 합시다. 예전에는 패턴 매칭 분해가 최선의 방법이었어요.
xs map {
case (x, y) => x + y
}
옳은 코드긴 한데 좀 불편하고 헷갈리기도 해요. case가 마치 패턴 매칭이 실패할 수도 있다는 뉘앙스를 주거든요. Scala 3에서는 더 짧고 명확한 대안을 쓸 수 있어요:
xs.map {
(x, y) => x + y
}
또는 동등하게:
xs.map(_ + _)
그리고:
def combine(i: Int, j: Int) = i + j
xs.map(combine)
일반적인 규칙은 이래요. n > 1 파라미터를 가진 함수 값은, 기대 타입이 그럴 때 ((T_1, ..., T_n)) => U 형태의 함수 타입으로 감싸져요. 그러면 튜플 파라미터가 분해되어 그 요소들이 바로 밑의 함수에 전달됩니다.
좀 더 정확히 말하면, 이 적응(adaptation)은 불일치하는 형식 파라미터 리스트에 적용돼요. 특히 함수 타입 사이의 변환은 아니에요. 그래서 다음은 받아들여지지 않습니다:
val combiner: (Int, Int) => Int = _ + _
xs.map(combiner) // Type Mismatch
파라미터를 언튜플링하는 대신, 함수 값을 명시적으로 튜플화해 줘야 해요:
xs.map(combiner.tupled)
강하게 권장되진 않지만, 같은 효과를 내도록 사용자 코드에서 암시적 변환을 제공할 수도 있어요:
import scala.language.implicitConversions
transparent inline given `fallback untupling`: Conversion[(Int, Int) => Int, ((Int, Int)) => Int] = _.tupled
xs.map(combiner)
파라미터 언튜플링은 변환이 적용되기 전에 시도되기 때문에, 스코프 안의 변환이 언튜플링을 무너뜨릴 수 없어요.
참고 (Reference)
더 자세한 내용은 다음을 참고하세요:
- 더 많은 세부 사항 (More details)
- 이슈 #897 (Issue #897).