[kotlin] 코틀린에서 람다식과 고차 함수를 사용하여 모나드(monad)를 구현하는 방법

모나드는 함수적 프로그래밍에서 핵심적인 개념으로, 일련의 연산을 추상화하고 조합하여 프로그램을 작성하는 데 도움을 줍니다. 이러한 모나드를 코틀린에서는 람다식과 고차 함수를 사용하여 구현할 수 있습니다. 이 포스트에서는 코틀린에서 모나드를 람다식과 고차 함수를 활용하여 어떻게 구현하는지 살펴보겠습니다.

람다식과 고차 함수란?

람다식은 이름이 없는 함수로, 변수에 저장하거나 함수의 인자로 전달할 수 있습니다. 코틀린에서는 val lambda: (Int) -> Int = { it * 2 } 와 같은 형식으로 정의할 수 있습니다.

고차 함수는 다른 함수를 매개변수로 받거나 함수를 반환하는 함수를 의미합니다. 코틀린에서는 fun myHigherOrderFunction(fn: (Int) -> Int): Int { ... } 와 같은 형식으로 정의할 수 있습니다.

모나드 구현하기

Option 모나드 구현

우선, Option 모나드를 람다식과 고차 함수를 사용하여 구현해 보겠습니다. Option 모나드는 값이 있을 수도 있고 없을 수도 있는 상황을 다룰 때 유용합니다.

sealed class Option<out T>

data class Some<out T>(val value: T) : Option<T>()
object None : Option<Nothing>()

fun <T, R> Option<T>.flatMap(f: (T) -> Option<R>): Option<R> = when (this) {
    is Some -> f(value)
    is None -> None
}

fun <T, R> Option<T>.map(f: (T) -> R): Option<R> = flatMap { Some(f(it)) }

fun <T> Option<T>.getOrElse(default: T): T = when (this) {
    is Some -> value
    is None -> default
}

위 코드에서 Option 모나드를 sealed class를 활용하여 정의하고, flatMap, map, getOrElse 함수를 구현합니다. 이를 통해 Option 모나드의 기본 동작을 정의하고 활용할 수 있습니다.

예제 사용하기

이제, Option 모나드를 사용하는 간단한 예제를 살펴보겠습니다.

val someValue: Option<Int> = Some(10)
val noneValue: Option<Int> = None

val result1 = someValue.flatMap { Some(it * 2) }.getOrElse(0)  // 20
val result2 = noneValue.flatMap { Some(it * 2) }.getOrElse(0)  // 0

위 예제에서는 flatMap 함수를 활용하여 Some 값이 있는 경우에는 연산을 수행하고, None 값이 있는 경우에는 기본값을 반환하는 것을 볼 수 있습니다.

결론

코틀린에서는 람다식과 고차 함수를 활용하여 모나드를 구현할 수 있습니다. 이를 통해 함수적 프로그래밍에서 모나드를 자연스럽게 활용할 수 있고, 코드를 보다 간결하고 추상화된 방식으로 작성할 수 있습니다. 모나드는 프로그래밍에서의 다양한 상황을 다루는 강력한 도구이며, 코틀린을 통해 이를 활용하는 방법을 살펴보았습니다.

참고문헌: