모나드의 이해

박형석·2021년 11월 30일
0

Swift

목록 보기
8/20
post-thumbnail

모나드?

모나드는 함수 내부에서 발생할 수 있는 사이드이펙트를 결과 집합과 함께 포함하는 타입이다. 함수 실행 결과를 항상 모나드로 반환하여 순수함수 성질을 잃지 않게 하는 것이다. 더 정확하게 얘기하자면 원시타입(boolean, int, string, float, double)과 커스텀 타입(class, struct)을 구체타입이라고 할 때 구체타입을 사용하여 함수의 인자와 결과값을 표현했다. 이 구체타입을 한 번 더 추상화한 것이 모나드입니다.

모나드와 함수형 아키텍처

함수객체와 모나드는 특정 기능이 아닌 디자인 패턴, 자료구조라고 할 수 있다. 옵셔널 체이닝, 옵셔널 바인딩, 플랫맵 등은 모나드와 관련된 연산이다. (스위프트의 기본 모나드 타입이 아니더라도 모나드 연산자를 사용하면 custom type을 모나드로 사용할 수 있다.)

모나드의 성질

  1. 타입을 인자로 받는 타입 (특정 타입의 값을 포장)
  2. 특정 타입의 값을 포장한 것을 반환하는 함수가 존재
  3. 포장된 값을 변환하여 같은 형태로 포장하는 함수가 존재

컨텍스트

  • '콘텐츠를 담은 그 무언가...'
  • 옵셔널의 경우, some case의 값이 Optional(enum)이라는 Context에 의해 Wrapped된 값.

함수객체

  • 맵을 적용할 수 있는 컨테이너 타입

모나드

  • 함수객체 중에서 자신의 컨텍스트와 같은 컨텍스트의 형태로 맵핑할 수 있는 함수객체
    == 닫힌 함수객체
    == 모나드
  • 함수객체와 동일하게 맵을 적용하면, 이 맵핑의 결과가 함수객체와 같은 컨텍스트를 반환함
    ex_ 옵셔널의 경우 map을 사용해도 같은 옵셔널로 나옴.
  • flatMap은 컨텍스트 내부의 컨텍스트를 모두 unwraping해서 같인 위상으로 평평하게 펼친다는 것. flatMap을 이용한 Unwrapping이 가능하다는 뜻...!
  • 모나드는 사이드 이팩트에 대한 대안이 존재 즉, U?으로 nil에 대한 처리가 가능. 그래서 flatMap을 사용할 수 있음.
func map<U>(_ transform: (Wrapped) throw -> U) rethrow -> U?
func flatMap<U>(_ transform: (Wrapped) throw -> U?) rethow -> U?
  • flatMap 메서드를 <Sequence 타입이 Optional 타입을 포장한 경우>에는 compactMap이라는 이름으로 사용한다.

기본 모나드 타입과 고차함수를 이용한 함수형 프로그래밍 하기

배열의 배열, 그 속의 옵셔널로 된 값들이 3중으로 컨테이너가 중첩되어 있을 때, 우리는 어떻게 1차원적인 배열을 얻을 수 있을까? 물론 옵셔널 바인딩을 통해 일일이 연산을 해줄 수도 있지만 옵셔널 체이닝이 많이 걸려있는 상태에서는 엄청 복잡한 코드가 될 것. 이때 위에서 배웠던 내용으로 간단히 구현이 가능하다.

func stringToInt(_ string: String) -> Int? {
 return Int(string)
}

fuc integerToStr(_ integer: Int) -> String? {
 return "\(integet)"
}

var optionalString: String? = "2"

let result = optionalString
.flatMap(stringToInt)
.flatMap(integerToStr)
.flatMap(stringToInt)

print(result) // Optional(2)
profile
IOS Developer

0개의 댓글