모나드는 함수 내부에서 발생할 수 있는 사이드이펙트를 결과 집합과 함께 포함하는 타입이다. 함수 실행 결과를 항상 모나드로 반환하여 순수함수 성질을 잃지 않게 하는 것이다. 더 정확하게 얘기하자면 원시타입(boolean, int, string, float, double)과 커스텀 타입(class, struct)을 구체타입이라고 할 때 구체타입을 사용하여 함수의 인자와 결과값을 표현했다. 이 구체타입을 한 번 더 추상화한 것이 모나드입니다.
함수객체와 모나드는 특정 기능이 아닌 디자인 패턴, 자료구조라고 할 수 있다. 옵셔널 체이닝, 옵셔널 바인딩, 플랫맵 등은 모나드와 관련된 연산이다. (스위프트의 기본 모나드 타입이 아니더라도 모나드 연산자를 사용하면 custom type을 모나드로 사용할 수 있다.)
func map<U>(_ transform: (Wrapped) throw -> U) rethrow -> U?
func flatMap<U>(_ transform: (Wrapped) throw -> U?) rethow -> U?
배열의 배열, 그 속의 옵셔널로 된 값들이 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)