카테고리 이론 기반의 함수형 타입 시스템과 펑터, 모나드와 같은 저주를 경험해 보자
함수형 타입 시스템
class A(val name: String, val phone: String) // A 에서 name과 phone는 결합되어 있다두 개 이상의 타입을 OR 조건으로 결합한 형태
코틀린에서는 sealed class 를 이용하여 합 타입을 생성한다
sealed class parent class A(val name: String) : parent() class B(val phoe: Int) : parent() // A와 B는 서로 다른 타입을 가지지만 parent라는 타입으로 묶인다
패턴 매칭이 쉽고 부수 효과가 존재하지 않는다
펑터!!
맵핑 할 수 있는 것 = map 함수 이라는 행위를 선언한 타입 클래스interface Functor<out A> { fun <B> map(f: (A) -> B) : Functor<B> }어플리케이티브 펑터 ( 이하 AF )
첫 번째 컨테이너의 함수와 두 번째 컨테이너의 값을 꺼내서 맵핑하고 다시 컨테이너에 넣어서 반환한다
함수를 가진 펑터에서 다른 펑터의 값을 적용해야 할 때, 컨텍스트 안에서 처리하는 것이 불가능한 점을 개선한 펑터
예시
interface Applicative<out A> : Functor<A> { fun <V> pure(value: V): Applicative<V> fun <B> apply(f: Applicative<A> -> B) : Applicative<B> fun <V,R> of(value: V) = { f: (V) -> R -> f(value) } }어플리케이티브 스타일 프로그래밍: 컨텍스트를 유지한 상태에서 함수에 의한 연속적 데이터 변환을 체이닝하는 방식의 프로그래밍 스타일
필수 조건
모노이드
연관 바이너리 함수와 항등 값을 지닌 대수적 타입
연관 바이너리 함수: 두 개의 매개변수와 반환 값의 타입이 동일한 함수
Fold형 자료구조를 만들 때 유용하다
항등값: 항등원을 조건을 만족하는 값
예시
interface Monoid<T> { fun mempty() : T // 항등원을 반환하는 함수 fun mappend(m1: T, m2: T) : T //바이너리 함수를 실행하고 반환 }필수조건
모나드
컨텍스트에 있는 값을 일반 값처럼 다룰 수 있도록 하는 컨테이너 타입
컨텍스트가 중첩되거나 함수가 일반 값을 매개변수로 받는 경우에도 컨텍스트를 유지하면서 연산이 가능하게 한다
펑터이자 어플리케이티브 펑터이다
예시
interface Monad<out A> : Functor<A> { fun <B> flatMap(f: (A) -> Monad<B>): Monad<B> fun <B> leadTo(m: Monad<B>): Monad<B> = flatMap { m } }필수 조건
팁
이더 모나드를 이용하여 실패 여부와 부가 정보를 포함하는 컨텍스트로 반환하여 처리한다
트라이 모나드를 이용하여 처리할 수도 있다 → 직접 만들 필요는 없다. 코틀린에 내재되어 있음(Result Class)