부분함수 : 모든 가능한 입력 중, 일부 입력에 대한 결과만 정의한 함수.
fun triple(x: Int) = x*3
fun partialTriple(x:Int) : Int = {
if(x>100) x*3
else {
throw IllegalArgumentException()
}
}
위의 예시와 같이 100이하의 숫자에 대해서(일부 입력에 대해서) 결과만 정의되어있고, 나머지는 exception을 출력한다.
이러한 함수를 부분함수하고 한다.
연습문제 4-1을 보며 익숙해져보자.
연습문제 4-1 : PartialFunction 클래스에 invokeOrElse 함수와 orElse 함수를 추가해보자.
invokeOrElse함수는 입력값 p가 조건에 맞지 않을 때 기본값 default를 반환한다.
orElse 함수는 PartialFunction의 입력값 p가 조건에 맞으면 PartialFunction을 그대로 반환하고 조건에 맞지 않으면 that을 반환한다.
fun main(){
val condition: (Int) -> Boolean = {it.rem(2) == 0}
val body : (Int) -> String = {"$it is even"}
val isEven = body.toPartialFunction(condition)
val target : Int = 99
if(isEven.isDefineAt(target)){
println(isEven(target))
}else {
println("isDefinedAt(X) return false");
}
}
class PartialFuntion<P, R> (
private val condition: (P) -> Boolean,
private val f :(P) -> R
) : (P) -> R {
override fun invoke(p: P) : R = when{
condition(p) -> f(p)
else -> throw IllegalArgumentException("$p isn't supported")
}
fun isDefineAt(p: P) : Boolean = condition(p)
// 연습문제 4-1
fun invokeOrElse(p: P, default : R) : R = when {
condition(p) -> f(p)
else -> default
}
fun orElse(p : P, that : PartialFuntion<P,R>) : PartialFuntion<P,R> = when {
this.isDefineAt(p) -> this
else -> that
}
}
fun <P,R> ((P)->R).toPartialFunction(definedAt : (P) -> Boolean)
: PartialFuntion<P,R> = PartialFuntion(definedAt, this);
invoke함수를 통해 가능한 입력인지 확인한 후 exception 여부를 결정한다.
하스켈과 같은 함수형 언어에서는 Maybe, Either를 반환하여 해당 부분을 처리하지만, 코틀린에서는 없기 때문에 위와 같이 부분함수를 구현하였다.
참고 문헌
코틀린으로 배우는 함수형 프로그래밍 (조재용, 우명인 지음) 인사이트
728x90
반응형
'프로그래밍 > 프로그래밍언어' 카테고리의 다른 글
[4장 고차함수] 커링함수 (2) | 2021.12.01 |
---|---|
[4장 고차함수] 4.3 부분 적용 함수 (0) | 2021.11.30 |
[4장 고차함수] 고차함수란 (0) | 2021.11.28 |
[3장 재귀] 3.7 실전 응용 - 멱집합 구하는 함수 (0) | 2021.11.19 |
[코틀린 설치] kotlin과 kotlin-native 코드 실행 (0) | 2021.11.17 |