1. Function.tupled
함수의 파라미터가 여러개의 값을 필요로 한다면 Function.tupled 메소드를 이용해 그 갯수만큼의 튜플을 입력받는 새로운 함수로 만들 수 있다.
def multiplyFunction(i: Int, j: Int): Int = i * j
val multiplyTuple: ((Int, Int)) => Int = Function.tupled(multiplyFunction _)
val multiplyUntupled: (Int, Int) => Int = Function.untupled(multiplyTuple)
val tupleValue = (10, 20)
println(multiplyTuple(tupleValue)) // 200
// multiplyFunction(tupleValue) // 에러
println(multiplyFunction(2, 2) == multiplyUntupled(2, 2)) // true
multiplyTuple을 Function.untupled 메소드를 이용해 다시 multiplyFunction과 같은 파라미터의 함수로 바꿀 수 있다.
2. Function.unlift
패턴 매칭에서 가장 자주 사용하는 부분 함수(Partial Function)는 단독적으로 사용할 경우 MatchError라는 잠재적 문제를 품고 있다.
val partialFunction: PartialFunction[String, String] = {
case "Hello" => "World"
}
println( partialFunction1("World") ) // scala.MatchError
"World"에 해당하는 동작이 정의되어 있지 않아 MatchError가 발생한다.
이런 상황을 방지하기 위해 case _를 정의하기도 한다.
부분 함수의 lift 메소드를 이용해 Option[T]를 반환하는 함수로 '끌어올릴' 수 있다. 반대로, Option[T]를 반환하는 함수를 Function.unlift 메소드를 이용해 부분 함수로 '끌어내릴' 수도 있다.
val partialFunction: PartialFunction[String, String] = {
case "Hello" => "World"
}
val liftPartialFunction: (String) => Option[String] = partialFunction.lift
println(liftPartialFunction("World")) // None
val partialFunction2: PartialFunction[String, String] = Function.unlift(liftPartialFunction)
println(partialFunction == partialFunction2) // true
쉽게 지나치지만 사실 개념적으로도 부분 함수는 Option[T]를 반환하는 함수와 같다.
3. Function.chain
함수들이 담긴 Sequence를 입력받아 Sequence의 함수들을 차례대로 실행하는 새로운 함수를 만들어준다.
val plus5: Int => Int = _ + 5
val multiply10: Int => Int = _ * 10
val functionSeq = Seq(plus5, multiply10)
val chainFunction = Function.chain(functionSeq)
println(chainFunction(7)) // multiply10(plus5(7))
// ( 7 + 5 ) * 10 = 120
4. Function.const
Function.const(R)(T)은 T => R과 같다. T를 입력받아 R을 반환한다. 각종 고차함수에 사용한다.
val functionConst: (Int, Int) => Int = Function.const(_:Int)(_:Int) // 커링
println(functionConst(10, 20)) // 10
println(functionConst(10, 100)) // 10
println(functionConst(20, 20)) // 20
val range = (1 to 3).map(Function.const(3))
println(range) // Vector(3, 3, 3)
커링을 염두에 두었는지 첫번째 파라미터가 반환하는 값 R이고, 두번째 파라미터가 입력값 T다.
'Scala' 카테고리의 다른 글
Scala의 Future의 map, for, recover (0) | 2017.04.16 |
---|---|
Scala의 함수 커링(Currying)과 표현 (0) | 2017.04.14 |
Java의 CompletableFuture, Scala의 Future와 Promise (0) | 2017.03.28 |
Scala의 암시(implicit) (1) | 2017.03.16 |
Java의 Comparator/Comparable, Scala의 Ordered/Ordering (0) | 2017.03.15 |