일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- Swift#flatMap#map#Monad#함수형 프로그래밍#Optional
- 합성
- 하향식 접근
- 다형성
- 유연한 설계
- 유여난 설계
- 객체지향
- 런타임 의존성
- 알고리즘
- 오브젝트
- 상속
- 책임주도설계
- 명령-쿼리 분리
- 서브 타이핑
- OOP
- 추상화
- Apple # HIG #iOS15 #iOS14 #Human #Interface #Guidelines #Apple developer # Apple human interface guidelines
- dip
- 행동 호환성
- 일관성 있는 협력
- 메서드를 통한 해결
- 믹스인
- 상속 조합 폭발적 증가
- 컴파일 타임 의존성
- '기존 설계 재사용
- iSP
- 설계 재사용
- OCP
- 객체 생성 사용 분리
- 의존성
Archives
- Today
- Total
도니의 iOS 프로그래밍 세상
[Swift] flatMap, map의 차이 - Monad로의 여정(1) 본문
함수형 프로그래밍에서 사용되는 말인 Monad에 대해서 설명하기 전, map 과 flatMap 의 차이점에 대해서 공부해보자
map과 flatMap은 차이점은 무엇일까?
가장 기본적인 차이점
- map의 경우 데이터를 변환하는데 사용된다
let cast = ["Vivien", "Marlon", "Kim", "Karl"]
let lowercaseNames = cast.map { $0.lowercased() }
// 'lowercaseNames' == ["vivien", "marlon", "kim", "karl"]
- flatMap은 2차원 이상의 배열들을 1차원 배열로 변환한다
let numbers = [1, 2, 3, 4]
let mapped = numbers.map { Array(repeating: $0, count: $0) }
// [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
let flatMapped = numbers.flatMap { Array(repeating: $0, count: $0) }
// [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
진정한 차이점
Optional 에서 map 만 사용해선, 우리는 함수 체이닝을 가독성이 좋은 구조로 구현할 수 없다.
이를 위해서, 우리는 필요한 상황에서 flatMap 을 사용해야 한다
실제 예시를 보면서 해당 의의를 이해하는것이 더 편하다
1. Optional에 map을 사용한 예시
let optString: String? = "33"
let result = optString.map { "3" + $0 }
// result의 타입은 String?, 값은 "333"
- 위의 경우, optString의 값이 nil이라면 nil이 리턴되고, nil이 아니라면 “333”이 리턴된다
- 기존에 guard let, if let등으로 불필요하게 값의 유무를 확인해서 벗기지 않아도 된다
하지만, 밑의 경우는 어떠할까?
let optString: String? = "33"
let result = optString.map { Int($0) }
// result 타입은 Int??, 값은 33
- Int 생성자에 string을 넣으면, Int(string: String) -> Optional(Int)이다.
- 결국, Int($0)의 리턴 타입은 Optional(Int)이다.
- 따라서, map 의 리턴 타입이 Int?? 이다.
- 만약 이럴때, map을 통해서 체이닝 하는것은 굉장히 번거로워진다.(Optional이 이중으로 wrapping된 상태이기에)
- 이때는 flatMap 을 사용한다
- 2. Optional에 flatMap을 사용한 예시
let optString: String? = "33"
let result = optString.flatMap { Int($0) }
// result 타입은 Int?, 값은 33
- flatMap을 통해 다음과 같이 Optional(Int) 를 리턴 받는다
- 이를통해, 우리는 map이나 flatMap을 통해 함수 체이닝을 구현할 수 있게 되었다
2. 두 함수 구현의 차이점
Optional 타입에서 map, flatMap의 정의는 다음과 같다.
func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?
func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U?
- map의 경우, transform 의 리턴 타입인 U에 Optional인 Optional(U) 를 리턴하는 구조이다.
- flatMap의 경우 transform 의 리턴 타입이, Optional(U) 이고, 리턴 타입또한 Optional(U) 이다.
이전 예시를 통해 그림으로 살펴보면 다음과 같다.(알파벳 맞추기와 동일하다)
- map은 transform 의 리턴 타입인 U 의 Optional 타입인 Optional(U) 를 리턴한다
- flatMap은 transform 의 리턴 타입인 Optional(U) 를 그대로 리턴한다.
결국, map은 transform 의 리턴 타입이 Optional 이 아닌 경우에 사용해야 한다.
flatMap은 transform 의 리턴 타입이 Optional 인 경우 사용한다.
이둘을 적절하게 사용할때, 우린 함수 체이닝을 가능하게 한다.
이들을 알아야 Monad 가 무엇인지 이해할 수 있다
결론
- map 과 flatMap 의 기본적인 차이는, array를 평탄화 시키거나, 값을 변경할때 사용된다.
- map, flatMap 의 적절한 사용은 함수 체이닝 을 가능하게 한다
- 이들은 Monad 를 이해하는데 필요한 요구 사항이다.
참조
https://developer.apple.com/documentation/swift/sequence/map(_:)
https://developer.apple.com/documentation/swift/sequence/flatmap(_:)
https://developer.apple.com/documentation/swift/optional/map(_:)
https://developer.apple.com/documentation/swift/optional/flatmap(_:)
'Swift' 카테고리의 다른 글
Group Task - Swift Concurrency(4) (0) | 2023.03.20 |
---|---|
Async let - Swift Concurrency(3) (0) | 2023.03.09 |
Swift Error handling(try, catch) - Swift Concurrency(2) (0) | 2023.02.09 |
Swift Concurrency(1) - 기본개념 및 작동원리 (0) | 2023.02.08 |
[Swift] ARC weak self를 하는 이유(delayed deinitialization, memory leak) - ARC 응용편 5탄 (0) | 2023.01.15 |
Comments