PHpullh
학습 라이브러리/Kotlin/프리즘 패턴 (Prism)

KOTLIN · 함수형

프리즘 패턴 (Prism)

프리즘은 합(sum) 타입의 특정 케이스에 초점을 맞추는 옵틱입니다. sealed class의 특정 분기를 안전하게 접근합니다.

함수형고급prismopticssealed-classsum-type

핵심 설명

프리즘은 합(sum) 타입의 특정 케이스에 초점을 맞추는 옵틱입니다. sealed class의 특정 분기를 안전하게 접근합니다.

Kotlin code

data class Prism<S, A>(
    val getOrNull: (S) -> A?,
    val reverseGet: (A) -> S
) {
    fun modify(source: S, f: (A) -> A): S =
        getOrNull(source)?.let { reverseGet(f(it)) } ?: source
}

sealed class Json {
    data class JString(val value: String) : Json()
    data class JNumber(val value: Double) : Json()
    data class JArray(val items: List<Json>) : Json()
    data object JNull : Json()
}

// 프리즘 정의
val jsonString = Prism<Json, String>(
    getOrNull = { (it as? Json.JString)?.value },
    reverseGet = { Json.JString(it) }
)

val jsonNumber = Prism<Json, Double>(
    getOrNull = { (it as? Json.JNumber)?.value },
    reverseGet = { Json.JNumber(it) }
)

fun main() {
    val str: Json = Json.JString("hello")
    val num: Json = Json.JNumber(42.0)

    println(jsonString.getOrNull(str))  // hello
    println(jsonString.getOrNull(num))  // null (안전)

    val upper = jsonString.modify(str) { it.uppercase() }
    println(upper)  // JString(value=HELLO)

    val doubled = jsonNumber.modify(num) { it * 2 }
    println(doubled)  // JNumber(value=84.0)
}

학습 팁

프리즘은 sealed class 계층을 다룰 때 패턴 매칭의 함수형 대안입니다. 렌즈와 합성하면 복잡한 데이터 접근이 가능합니다.

주의할 점

프리즘의 getOrNull이 실패하면 modify는 원본을 그대로 반환합니다. 이는 의도된 동작이지만 실수로 무시될 수 있으니 반환값을 확인하세요.

자주 묻는 질문

프리즘 패턴 (Prism)란 무엇인가요?

프리즘은 합(sum) 타입의 특정 케이스에 초점을 맞추는 옵틱입니다. sealed class의 특정 분기를 안전하게 접근합니다.

프리즘 패턴 (Prism) 학습 시 주의할 점은 무엇인가요?

프리즘의 getOrNull 이 실패하면 modify 는 원본을 그대로 반환합니다. 이는 의도된 동작이지만 실수로 무시될 수 있으니 반환값을 확인하세요.