Scala

Scala Function Object의 메소드들

partner_jun 2017. 4. 1. 22:23


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다.