ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift] 모나드(Monad)
    iOS/Swift 2022. 8. 15. 15:45

     

    모나드

    • 값을 어딘가에 포장하는 개념에 대한 이해에서 출발한다
    • 함수객체(Functor)와 모나드(Monad)는 특정 기능이 아닌 디자인 패턴 혹은 자료구조라고 할 수 있다

     

    모나드가 갖춰야하는 조건 3가지

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

     

    모나드의 대표적인 예시: 
    🔥 옵셔널 - 값이 있을지 없을지 모르는 상태를 박스에 담아두는 것

    옵셔널은 
    (1) Wrapped 타입을 인자로 받는 제네릭 타입이다
    (2) Optional<Int>, init(2) 처럼 다른 타입의 값을 갖는 상태의 컨텍스트를 생성할 수 있다
    (3) 옵셔널은 컨테이너와 값을 갖기 때문에 맵 함수를 사용할 수 있다

     

     

    모나드를 이해하기 위해 필요한 개념

    1. 컨텍스트(Context)

    2. 함수객체(Functor)

     


    컨텍스트(Context)

    스위프트에서 컨텍스트는 콘텐츠를 담은 그 무엇인가(박스)이다

    ex)
    2라는 숫자를 옵셔널로 둘러싸면 컨텍스트 안에 2라는 콘텐츠가 들어가있는 것이다.
    = 컨텍스트는 2라는 값을 가지고 있다

    값이 없는 옵셔널 상태라면 컨텍스트는 존재하지만 내부에 값이 없다고 할 수 있다

     

    // MARK: 컨텍스트
    func add(_ num: Int) -> Int {
        return num + 3
    }
    
    print(add(2))       //순수값 2를 전달하면 정상적으로 함수를 실행할 수 있다
    // print(Optional(2)) 순수값이 아닌 컨텍스트로 둘러싸인 값이 전달되었기 때문에 오류
    
    
    // map 메서드를 사용하여 옵셔널 연산
    print(Optional(2).map(add)) //Optional(5)
    //map함수는 연산 결과를 다시 컨텍스트에 넣어 반환

     


    함수객체

    닫힌 함수객체(Endofunctor)

    • 자신의 컨텍스트와 같은 컨텍스트의 형태로 맵핑할 수 있는 함수객체
    • 고차함수인 map을 적용 할 수 있는 컨테이너 타입
    • 모나드는 닫힌 함수객체이다

     

    플랫맵(flatMap) 메서드 활용

    // MARK: flatMap 활용
    func doubledEven(_ num: Int) -> Int? {
        if num.isMultiple(of: 2) {
            return num * 2
        }
        return nil
    }
    
    print(Optional(6).flatMap(doubledEven(_:)))     //Optional(12)
    print(Optional(3).flatMap(doubledEven(_:)))     //nil

     

    맵과 플랫맵(컴펙트맵)의 차이점

    
    /* map과 flatMap의 차이 */
    // 플랫맵(컴팩트맵)은 컨텍스트 내부의 컨텍스트를 모두 같은 위상으로 평평하게 펼쳐준다
    
    let optionals: [Int?] = [1, 2, nil, 5]
    
    let mapped: [Int?] = optionals.map{ $0 }            //[Optional(1), Optional(2), nil, Optional(5)]
    let flatmapped: [Int] = optionals.compactMap{ $0 }  //[1, 2, 5]
    
    print(mapped)       //결과를 다시 Array 컨테이너에 담는다
    print(flatmapped)   //내부 컨테이너까지 값을 추출한다

     

    'iOS > Swift' 카테고리의 다른 글

    [Swift] 상속 (Inheritance)  (0) 2022.08.22
    [Swift] 서브스크립트(subscript)  (0) 2022.08.20
    [Swift] 맵, 필터, 리듀스(map, filter, reduce)  (0) 2022.08.15
    [Swift] 옵셔널 체이닝(Optional Chaining)  (0) 2022.08.11
    [Swift] 클로저  (0) 2022.08.09
Designed by Tistory.