욱'S 노트

함수형 데이터구조/대수적 타입/Algebraic Data Type (Kotlin 함수형프로그래밍 #3) 본문

Methdology/Functional Programming

함수형 데이터구조/대수적 타입/Algebraic Data Type (Kotlin 함수형프로그래밍 #3)

devsun 2025. 1. 13. 09:46
반응형

대수적 타입(ADT)

대수적 타입 즉 Algrebraic Data Type은 합타입과 곱타입으로 표현된 타입이다. 그렇다면 합타입과 곱타입이란 무엇인가?

합타입

대표적으로 enum class가 있다. 아래의 RGB 타입은 RED, GREEN, BLUE 3가지만 존재할 수 있다.

enum class RGB {
    RED(),
    GREEN(),
    BLUE()
}

곱타입

대표적인 예로 class가 있다.

data class Person(val name: String, val age: Int, val email: String)

val lazysoul = Person("lazysoul", 33, "kotlin@gmail.com")
val goinhacker = Person("goinhacker", 36, "fp@gmail.com")
val myeongin = Person("myeongin", 33, "myeongin@gmail.comm")

Person객체는 String, Int, String 3개 타입의 프로퍼티로 구성되어있다. 즉 표현할 수 있는 값은 (String으로 표현할 수 있는 갯수) * (Int로 표현할 수 있는 갯수) * (String으로 표현할 수 있는 갯수)이다. 이런 타입을 곱타입이라고 한다.

장점

코클린에서 enum class와 sealed class가 대수적 타입이다. 합타입을 패턴매칭에서 모든 타입에 대한 구현을 컴파일러 레벨에서 강제할 수 있다. Arrow에서 제공하는 가장 기본적인 대수적 타입의 클래스는 Either이다.

sealed class Either<out E, out A>
data class Left<out E>(val value: E) : Either<E, Nothing>()
data class Right<out A>(val value: A) : Either<Nothing, A>()

 

 

만약 합타입과 곱타입으로 제한된 대수적 타입을 사용하지 않았다면, 항상 when절에서 미지의 상태를 위한 else 처리를 해야된다.

    val actual = if (newDeposit.amount > 0)
        Right(newDeposit.amount)
    else
        Left(DepositNotEnoughError)

    when (actual) {
        is Right -> TODO("Not implemented yet")
        is Left -> TODO("Not implemented yet") 
        // no need else
    }

 

불변 리스트/ 불변 트리

불변 리스트의 간단한 구현을 살펴봐도 ADT 형태로 되어 있다는 것을 알 수 있다.

아래 코드에서 List<out A>에서 A가 List의 공변적이라는 신호를 보내는 변성 어노테이션이다.  타입 X, Y에 대해 X가 Y의 하위 타입이면 List<X>도 List<Y>의 하위 타입이다. 구현에서 Nothing는 코틀린에서 모든 타입의 하위 타입이므로 Nil은 List<Int>로 간주 될 수 있고 List<Double>로 간주 될 수도 있다.

// sealed 키워드를 통해 패키지 안에서만 상속 가능하도록
sealed class List<out A>

// Empty를 표현
object Nil : List<Nothing>()

// 비어 있지 않는 리스트
data class Cons<out A>(val head: A, val tail: List<A>) : List<A>()

// 연결 함수
fun <A> append(a1: List<A>, a2: List<A>): List<A> =
    when (a1) {
        is Nil -> a2
        is Cons -> Cons(a1.head, append(a1.tail, a2))
    }

 

불변 트리를 생각해보더라도 핵심은 ADT이다. 

sealed class Tree<out A>

data class Leaf<A>(val value: A) : Tree<A>()

data class Branch<A>(val left: Tree<A>, val right: Tree<A>) : Tree<A>()

 

정리

  • 대수적 타입은 합타입과 곱타입으로 표현된 타입니다. 
  • 대수적 타입을 사용하면 패턴 매칭등을 통해 모든 경우에 대한 처리를 컴파일러 레벨에서 검사할 수 있다.

 

참조 : https://medium.com/@lazysoul/%EB%8C%80%EC%88%98%EC%A0%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EC%9D%B4-algebraic-data-type-%EC%9D%B4%EB%9E%80-26d9e73d96b6

 

대수적 데이터 타입이(algebraic data type)이란? With Kotlin

함수형 프로그래밍을 공부하면 대수적(algebraic)이라는 표현을 접하게 됩니다. 아는것 같았지만.. 막상 설명하라고 하면 못하는… 항상 애매하게, 두리뭉실하게 넘어가다가 이번에 정리를 합니다

medium.com

https://www.yes24.com/Product/Goods/120236288?pid=123487&cosemkid=go16903580741098008&utm_source=google_pc&utm_medium=cpc&utm_campaign=book_pc&utm_content=ys_240530_google_pc_cc_book_pc_12306%EB%8F%84%EC%84%9C&utm_term=%EC%BD%94%ED%8B%80%EB%A6%B0%ED%95%A8%EC%88%98%ED%98%95%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D&gad_source=1&gclid=CjwKCAiAm-67BhBlEiwAEVftNp4rJHRMrNaBE2YyQCT-r4Gxu_X9K6NdakIvehx_Mxsi48Jj3rZ45BoCbUsQAvD_BwE

 

코틀린 함수형 프로그래밍 - 예스24

함수형 프로그래밍을 들어본 개발자는 많지만 제대로 된 함수형 프로그래밍을 배우기 위해 하스켈이나 스칼라까지 배울 여유가 없는 독자도 많을 것이다. 이 책은 정석적인 함수형 프로그래밍

www.yes24.com

 

반응형