[swift-users] Rational behind having 2 different behaviors for flatMap?

Saagar Jha saagar at saagarjha.com
Mon Feb 13 19:35:07 CST 2017


Hmm, it looks like you’re right. I could swear I’ve used flatMap without a closure before…oh well, looks like that’s what happens when you send code without running it in a Playground.

Saagar Jha

> On Feb 13, 2017, at 5:33 PM, Jon Shier <jon at jonshier.com> wrote:
> 
> According to the compiler, the closure argument for flatMap is not optional or defaulted, so it’s always required. I think it should default to { $0 }, but whatever.
> 
> 
> Jon
> 
>> On Feb 13, 2017, at 8:26 PM, Saagar Jha via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> wrote:
>> 
>> flatMap was designed to work this way. How I rationalize it is that flatMap “extracts” the value from an array’s elements and expands it. For an Array, this is just taking out the individual Elements, but for an Optional, which a “wrapper” around one value, it just takes this value out. Optionals with no value (the .none case, or nil as it’s more commonly known) have nothing to contribute and thus are filtered out.
>> 
>> Saagar Jha
>> 
>> P.S. You can call flatMap without a closure: deep.flatMap().flatMap()
>> 
>>> On Feb 13, 2017, at 4:31 PM, Maxim Veksler via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> wrote:
>>> 
>>> Hi everyone,
>>> 
>>> I've discovered today that Swift will actually choose 2 very differently behaving types of flatMap implementation based on the input signature. 
>>> 
>>> For a Sequence of options it will call a flatMap that filters out nil's. For a Sequence of Sequence's it will call a flattening function, without filtering.
>>> 
>>> Leading to code that (IMHO) reads very not inconsistency, and unexpected. Sometime even looking a bit funny such as collection.flatMap.flatMap:
>>> 
>>>   5> let deep = [["1989", nil], [nil, "Red"], [nil, nil]]
>>> deep: [[String?]] = 3 values {
>>>   [0] = 2 values {
>>>     [0] = "1989"
>>>     [1] = nil
>>>   }
>>>   [1] = 2 values {
>>>     [0] = nil
>>>     [1] = "Red"
>>>   }
>>>   [2] = 2 values {
>>>     [0] = nil
>>>     [1] = nil
>>>   }
>>> }
>>>   6> deep.flatMap { $0 }
>>> $R1: [String?] = 6 values {
>>>   [0] = "1989"
>>>   [1] = nil
>>>   [2] = nil
>>>   [3] = "Red"
>>>   [4] = nil
>>>   [5] = nil
>>> }
>>>   7> deep.flatMap { $0 }.flatMap { $0 }
>>> $R2: [String] = 2 values {
>>>   [0] = "1989"
>>>   [1] = "Red"
>>> }
>>> I wonder why it was implemented this way?
>>> 
>>> 
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org <mailto:swift-users at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-users <https://lists.swift.org/mailman/listinfo/swift-users>
>> 
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org <mailto:swift-users at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-users
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170213/d21fa396/attachment.html>


More information about the swift-users mailing list