<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Nov 15, 2017, at 10:39 AM, Tino Heth via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">So conceptionally, both overrides are equivalent: The transformation always produces something — an Optional, and that can contain a value, or it can be empty, just like an array.</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">You also see that the flatten step really does what it says: It removes one layer of objects, and leaves a flush surface without gaps.</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">So, that should really be my last word in this discussion — I won’t add an animation or start singing about Optionals ;-)</div></div></blockquote></div><div class=""><br class=""></div><div class="">Your logic makes sense but doesn’t account for where “flatMap” came from and the expectations of how “flatMap” should work.</div><div class=""><br class=""></div><div class="">In functional programming, “map” must preserve structure (the container shape should stay the same), and “flatMap” must use the same structure throughout, including the return value of the higher order function it takes.</div><div class=""><br class=""></div><div class="">map :: (a -&gt; b) -&gt; m a -&gt; m b</div><div class="">flatMap :: (a -&gt; m b) -&gt; m a -&gt; m b</div><div class=""><br class=""></div><div class="">You may argue that Swift isn’t really a functional language and doesn’t have to adhere to functional rules, but as long as it adopts functional nomenclature, it should do its best to behave with functional expectations. It’s actually impossible to write “flatMap” as written above against a protocol like Sequence because Swift lacks higher kinded types, but we can at least approximate the behavior that functional programmers expect by narrowing the scope of what’s appropriate to return from that higher order function, which is in this case a sequence (of which Optional is not).</div><div class=""><br class=""></div><div class="">In fact, I’d rather make “flatMap” stricter by requiring that higher order function to return an Array! This of course would kill some ergonomics, but it’d at least make things easier to reason about when you always get an Array out the other side.</div><div class=""><br class=""></div><div class="">Stephen</div><div class=""><a href="https://www.pointfree.co" class="">https://www.pointfree.co</a></div></body></html>