如何解决Swift 中 flatMap 的定义
我正在研究函子和单子。所以我知道函子使用 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)。
然后,我只想检查 map
、flatMap
和 Optional
中 Result
和 Array
的定义。因为我听说那些也是 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 会应用一个返回包装值到包装值的函数,所以我期望 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>
时。
flatMap
中的 Array
不仅针对 SegmentOfResult == Array<T>
的情况定义,还针对任何 SegmentOfResult
定义为 Sequence
。
为什么?因为我们想定义函数,以便它们可以处理尽可能多的类型(即尽可能通用)。事实证明,如果函数映射到任何 flatMap
,Sequence
也可以工作。也就是说,它不依赖于函数专门返回 Array
的事实。它仅取决于函数返回某种 Sequence
的事实。如果您有兴趣,请查看 flatMap
如何实现 here。
出于同样的原因,flatMap
不仅适用于 Array
,它还适用于任何符合 Sequence
的类型!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。