Swift 中的 flatMap 定义
Definition of flatMap in Swift
我正在研究仿函数和monad。所以我知道仿函数使用 map
而 monad 使用 flatMap
,而且 map
和 flatMap
的定义如下所示。
enum Box<T> {
case some(T)
case empty
}
extension Box {
func map<U>(_ f: @escaping (T) -> U) -> Box<U> {
// ...
}
}
extension Box {
func flatMap<U>(_ f: (T) -> Box<U>) -> Box<U> {
// ...
}
}
我完全明白那些正在使用不同的 f
参数(感谢 this article)。
然后,我只想检查Optional
、Result
和Array
中map
和flatMap
的定义。因为我听说那些也是 monad。在 Optional
和 Result
中,定义看起来与上面的自定义 map
和 flatMap
相同。
但在 Array
中没有。
func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence
我现在有点困惑。因为我知道一个 monad 应用了一个 returns 包装值到包装值的函数,所以我期望 flatMap
的定义如下所示(绝对错误)。
func flatMap<T>(_ transform: (Element) throws -> [T]) rethrows -> [T]
但无论如何都不是。
我错过了什么吗?我误解的地方在哪里?
你在期待
func flatMap<T>(_ transform: (Element) throws -> Array<T>) rethrows -> Array<T>
对于 Array
。
如果你仔细观察,以上只是你发现的签名的一个特例,当SegmentOfResult == Array<T>
.
Array
中的 flatMap
不仅适用于 SegmentOfResult == Array<T>
的情况,而且适用于 Sequence
的任何 SegmentOfResult
。
为什么?因为我们想定义函数,以便它们可以在尽可能多的类型上工作(即尽可能通用)。事实证明,如果函数映射到任何 Sequence
,flatMap
也可以工作。也就是说,它不依赖于函数 returns 特别是 Array
这一事实。它仅取决于函数 returns 某种 Sequence
的事实。如果您有兴趣,请查看 flatMap
是如何实现的 here。
出于同样的原因,flatMap
不仅适用于 Array
,它适用于任何符合 Sequence
!
的类型
我正在研究仿函数和monad。所以我知道仿函数使用 map
而 monad 使用 flatMap
,而且 map
和 flatMap
的定义如下所示。
enum Box<T> {
case some(T)
case empty
}
extension Box {
func map<U>(_ f: @escaping (T) -> U) -> Box<U> {
// ...
}
}
extension Box {
func flatMap<U>(_ f: (T) -> Box<U>) -> Box<U> {
// ...
}
}
我完全明白那些正在使用不同的 f
参数(感谢 this article)。
然后,我只想检查Optional
、Result
和Array
中map
和flatMap
的定义。因为我听说那些也是 monad。在 Optional
和 Result
中,定义看起来与上面的自定义 map
和 flatMap
相同。
但在 Array
中没有。
func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence
我现在有点困惑。因为我知道一个 monad 应用了一个 returns 包装值到包装值的函数,所以我期望 flatMap
的定义如下所示(绝对错误)。
func flatMap<T>(_ transform: (Element) throws -> [T]) rethrows -> [T]
但无论如何都不是。
我错过了什么吗?我误解的地方在哪里?
你在期待
func flatMap<T>(_ transform: (Element) throws -> Array<T>) rethrows -> Array<T>
对于 Array
。
如果你仔细观察,以上只是你发现的签名的一个特例,当SegmentOfResult == Array<T>
.
Array
中的 flatMap
不仅适用于 SegmentOfResult == Array<T>
的情况,而且适用于 Sequence
的任何 SegmentOfResult
。
为什么?因为我们想定义函数,以便它们可以在尽可能多的类型上工作(即尽可能通用)。事实证明,如果函数映射到任何 Sequence
,flatMap
也可以工作。也就是说,它不依赖于函数 returns 特别是 Array
这一事实。它仅取决于函数 returns 某种 Sequence
的事实。如果您有兴趣,请查看 flatMap
是如何实现的 here。
出于同样的原因,flatMap
不仅适用于 Array
,它适用于任何符合 Sequence
!