Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
461 views
in Technique[技术] by (71.8m points)

monads - Definition of flatMap in Swift

I was studying a functor and monad. So I got to know that a functor uses map and a monad uses flatMap, and also that definition of map and flatMap looks like below.

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> {
        // ...
    }
}

I totally got those are using different f parameter(Thanks for this article).

Then, I just wanted to check definition of map and flatMap in Optional, Result and Array. Because I heard those are monad as well. In Optional and Result, the definition looks like same as custom map and flatMap above.

But in Array, does not.

func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]

func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence

I'm bit confused now. Because I knew a monad apply a function that returns wrapped value to wrapped value, so I expected the definition of flatMap looking like below(definitely wrong).

func flatMap<T>(_ transform: (Element) throws -> [T]) rethrows -> [T]

But It's not anyway.

Am I missing something? Where is the point that I misunderstood?

question from:https://stackoverflow.com/questions/65950112/definition-of-flatmap-in-swift

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You were expecting

func flatMap<T>(_ transform: (Element) throws -> Array<T>) rethrows -> Array<T>

for Array.

If you look closely, the above is merely a special case of the signature that you found, when SegmentOfResult == Array<T>.

The flatMap in Array is defined not just for the case when SegmentOfResult == Array<T>, but also for any SegmentOfResult that is a Sequence.

Why? Because we would like to define functions so that they work on as many types as possible (i.e. as general as possible). It turns out that flatMap would also work if the function mapped to any Sequence. That is, it doesn't depend on the fact that the function returns specifically an Array. It only depends on the fact that the function returns some kind of a Sequence. Check out how flatMap is implemented here if you are interested.

For the same reason, flatMap isn't just available on Array, it's available on any type that conforms to Sequence!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...