-
Endofunctor (엔도펑터), 모나드 (Monad)Development/Architecture 2026. 3. 2. 18:36반응형
엔도펑터 (Endofunctor)
출발하는 카테고리와 도착하는 카테고리가 같은 펑터로, 그리스어 접두사 'Endo-'(내부의)와 의미와 Functor가 결합한 것이다. 프로그래밍에서 다루는 대부분의 펑터가 엔도펑터다. 가장 흔한 예시로 Maybe(or 자바의 Optional)가 있다. (F : C -> C)
엔도펑터 역시 펑터와 마찬가지로 대상 객체를 매핑하는 것 뿐만 아니라 사상 또한 매핑해야 한다. 이를 리프팅(lifting) 한다고 하며, 들어올린다고도 한다.
ex) a -> b를 Maybe a -> Maybe b 로 리프팅
모나드 (Monad)
모나드는 엔도펑터 카테고리에서의 모노이드다. 즉, 결합 법칙과 항등 법칙을 만족해야 한다.
- 펑터는 컨텍스트 안의 값을 바꾸는 함수를 적용한다.
- map : F<A> -> (A -> B) -> F<B>
- 함수가 컨텍스트를 생성하지는 않는다.
- 모나드는 컨텍스트 안의 값에 컨텍스트를 생성하는 함수를 적용한다.
- flatMap : M<A> -> (A -> M<B>) -> M<B>
- 함수 자체가 새로운 컨텍스트를 반환한다.
sealed class Maybe<out A> { data class Just<A>(val value: A) : Maybe<A>() data object Nothing : Maybe<kotlin.Nothing>() fun <B> map(f: (A) -> B): Maybe<B> = when (this) { is Just -> Just(f(value)) is Nothing -> Nothing } fun <B> flatMap(f: (A) -> Maybe<B>): Maybe<B> = when (this) { is Just -> f(value) is Nothing -> Nothing } } // ── 순수한 변환: 펑터로 충분 val number: Maybe<Int> = Maybe.Just(42) val doubled: Maybe<Int> = number.map { it * 2 } // Just(84) val asString: Maybe<String> = number.map { it.toString() } // Just("42") // ── 실패 가능한 연산: 펑터만으로는 한계 fun safeDivide(a: Int, b: Int): Maybe<Int> = if (b != 0) Maybe.Just(a / b) else Maybe.Nothing val result: Maybe<Maybe<Int>> = number.map { safeDivide(it, 0) } // 결과: Just(Nothing) — Maybe가 이중으로 중첩됨. // 타입이 Maybe<Maybe<Int>>가 되어버림. // ── 모나드의 flatMap이 해결 val clean: Maybe<Int> = number.flatMap { safeDivide(it, 0) } // 결과: Nothing — 평탄화됨.반응형'Development > Architecture' 카테고리의 다른 글
함수형 프로그래밍, 커링, 모노이드, 펑터.. (0) 2026.02.18 아키텍처 퀀텀 (Architecture Quantum) (0) 2026.02.17 [Domain Driven Design] 도메인 모델 정리 (1) 2021.05.25 [Clean Architecture] 컴포넌트 결합 (0) 2020.06.29 [Clean Architecture] 컴포넌트 응집도 (0) 2020.06.27 - 펑터는 컨텍스트 안의 값을 바꾸는 함수를 적용한다.