티스토리 뷰
Monad(모나드)]
출처: [위키백과 - 모나드](https://ko.wikipedia.org/wiki/%EB%AA%A8%EB%82%98%EB%93%9C)
Monadic(모나딕)
모나드는 여러 영역에서 다양한 뜻을 가지기도 하고 한 문장으로 설명하기 어려운 개념이라서 범주론의 모나드 개념을 차용한 정도로 생각하면 될 것 같습니다.
모나드는 순서가 있는 연산을 처리할 때 자주 활용하는 디자인 패턴입니다.
프로그래밍에서는 모나드의 성질의 대부분을 갖추었다고 하여 모나드를 모나딕(monadic) 이라고 표현합니다. (모나딕 타입 혹은 모나딕 함수)
🧬
모나드
함수 내부에서 발생할 수 있는 사이드이펙트를 결과 집합과 함께 포함하는 타입
함수형 프로그래밍을 이해하는데 모나드는 도움이 될거에요! 결과로 항상 모나드를 반환하여 순수함수 성질을 잃지 않게 하는 것이기 때문입니다.
🧬
순수함수
외부 상태에 의존적이지 않고, 어떠한 사이드이펙트도 발생시키지 않는 함수
순수함수는 언제 얼마나 많이 호출해도 항상 같은 매개변수에 대해 같은 결과를 반환합니다.
즉, Int, String, Float, Bool, Class, Struct 를 사용해서 함수의 파라미터와 리턴값을 표현했는데 한 번 더 추상화한 것이 모나드
입니다.
프로그래밍에서 모나드가 갖춰야 하는 조건
1️⃣ 타입을 인자로 받는 타입(특정 타입의 값을 포장) → 제네릭
2️⃣ 특정 타입의 값을 포장한 것을 반환하는 함수(메서드)가 존재
3️⃣ 포장된 값을 변환하여 같은 형태로 포장하는 함수(메서드)가 존재
💫 Optional(옵셔널) 은 모나드의 예시 입니다.
스위프트에서 모나드를 사용한 예시 중 하나가 옵셔널
입니다.
옵셔널은 열거형!
: 값이 있을지 없을지 모르는 상태를 포장
하는 것.
Context(컨텍스트)
Contents(콘텐츠) 를 담는 그 무언가.
옵셔널을 떠올리면 값이 없다면 .none case 로 있다면 .some(value) case 로 값을 지닙니다.
- 2라는 숫자를 옵셔널로 둘러싸면? → 컨텍스트 안에 2라는 콘텐츠가 들어가는 모양입니다.
- 값이 없는 옵셔널이라면? → 컨텍스트는 존재하지만 내부 값이 없다.
조건 충족
1️⃣ 옵셔널은 Wrapped 타입을 인자로 받는 제네릭 타입.
2️⃣ 콘텐츠의 타입을 갖는 컨텍스트를 반환.
3️⃣ map! map?
🧬
map
은 컨테이너(다른 타입의 값을 담을 수 있으므로 컨텍스트 역할을 할 수 있다.)의 값을 변형시킬 수 있는 고차함수
옵셔널은 컨테이너와 값을 갖기 때문에map
함수를 사용할 수 있다.
var value: Int? = 2
value.map { $0 + 3 } // Optional(5)
value = nil
value.map { $0 + 3 } // nil
💫 또한, 모나드는 닫힌 함수객체
입니다.
함수 객체?(Functor)
맵
을 적용할 수 있는 컨테이너 타입. 즉, 함수 객체는 포장된 값에 함수를 적용할 수 있습니다.
닫힌 함수객체?(Endofunctor)
자신의 컨텍스트와 같은 컨텍스트의 형태로 맵핑할 수 있는 함수 객체를 닫힌 함수객체
(Endofunctor)라고 합입니다.
모나드
는 닫힌 함수객체
입니다.
즉, 모나드는 결과가 함수객체와 같은 컨텍스트를 반환하는 함수객체라고 할 수 있고, 이런 맵핑을 수행하도록 flatMap
을 활용합니다.
flatMap
맵과 같이 함수를 매개변수로 받지만, 컨텍스트 내부의 컨텍스트를 모두 같은 위상으로 평평하게 펼쳐준다는 차이가 있습니다.
flatMap 을 사용해 보겠습니다.
// 옵셔널과 flatMap 을 사용할 수 있나요?
// 네! 옵셔널은 모나드이기 때문이죠.
let optionalArray: [Int?] = [1, 2, 3, 4, nil]
// [Optional(1), Optional(2), Optional(3), Optional(4), nil]
let flatMappedArray = optionalArray.flatMap { $0 }
// [1, 2, 3, 4]
// 2차원 배열을 1차원 배열로 flatten 하게 만들어준다.
let nestedArray: [[Int]] = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flatMappedNestedArray = nestedArray.flatMap { $0 }
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
let nestedNilArray: [[Int?]] = [[1, 2, nil], [4, nil, nil], [7, 8, 9]]
let flatMappedNestedNilArray = nestedNilArray.flatMap { $0 }
// [Optional(1), Optional(2), nil, Optional(4), nil, nil, Optional(7), Optional(8), Optional(9)]
let optional: Int? = 8
let value = optional.flatMap { $0 > 0 ? $0 : -$0 }
// Optional(8)
flatMap 의 기능
- non-nil 의 배열을 리턴
- 주어진 Sequence 내의 요소들을 하나의 배열로써 리턴
- 주어진 Optional 이 not-nil 인지 판단 후 unwrapping 하여 closure 파라미터로 전달
⚠️경고
💫 flatMap(_:)
- Deprecated. non-nil 배열을 리턴하는 기능이 dprecated 되었습니다.
- 위의 기능을 제외한 클로저가 옵셔널 변수를 리턴하지 않는 경우는
flatMap
을 그대로 사용하면 되겠습니다.
💫 compactMap
- non-nil 배열을 리턴.(deprecated 된 flatMap 과 declaration 이 동일하다.)
flatMap 과 Map 이랑 다른점은?
- 정수형으로 변환하기위해서
Int()
를 사용해서 int 옵셔널변수를 리턴하는 경우
// flatMap 은 클로저를 실행하면 내부 컨테이너까지 값을 추출한다.
let optionalInt: String? = "3"
let flatMappedOptionalString = optionalInt.flatMap { Int($0) }
// Optional(3)
// map 은 클로저 코드를 실행하고, 결과를 다시 컨테이너에 담기만 한다.
let mappedOptionalString = optionalInt.map { Int($0) }
// Optional(Optional(3))
출처:
- 스위프트 프로그래밍(3판) / 야곰
'iOS' 카테고리의 다른 글
iOS) async/await 와 URLSession 사용하기(2) - abstraction layer 구축해보기 (2) | 2022.06.03 |
---|---|
iOS) async/await 와 URLSession 사용하기(1) - async/await (2) | 2022.06.03 |
iOS) 앱 심사 리젝 해결(Guideline 5.1.1 / 5.1.2) (0) | 2022.05.05 |
iOS) 강제 업데이트, 최신버전 확인 후 업데이트 (11) | 2022.04.28 |
iOS) Shadowing 에 대해서 생각해보자 (0) | 2022.04.21 |
- RxCocoa
- 2022 KAKAO TECH INTERNSHIP
- Firebase
- configurable widget
- rxswift
- github
- IOS
- SwiftUI
- Protocol
- WidgetKit
- WWDC
- 서버통신
- APNS
- urlsession
- containerBackground
- CloneCoding
- MOYA
- OpenSourceLibrary
- MVVM
- async/await
- Widget
- projectsetting
- Algorithm
- Notification
- watchOS
- Swift
- YPImagePicker
- UserDefaults
- WWDC22
- Objective-C
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Total
- Today
- Yesterday