<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>That definition is unusable, since it restricts the type of the map operation to be whatever type you chose when you implemented the protocol.<br></div>
<div> </div>
<div>To see this for yourself, try implementing Functor on Array. You can't do it, unless you pick the B type ahead of time, and if you do that you can only ever map() to that single type B. The map() function is supposed to be generic on the result type of the function, but since Swift doesn't have higher-order types there's no way to express that the result of the map() function is the same underlying data structure with a separate generic parameter.<br></div>
<div> </div>
<div>-Kevin Ballard</div>
<div> </div>
<div> </div>
<div>On Fri, Dec 4, 2015, at 08:56 PM, Harlan Haskins wrote:<br></div>
<blockquote type="cite"><pre style="white-space:pre-wrap;background-color:rgb(255, 255, 255);"><br></pre><div>Y’know, <span class="font" style="font-family:Menlo">map</span> and <span class="font" style="font-family:Menlo">flatMap </span>being part of <span class="font" style="font-family:Menlo">SequenceType</span> is really a misnomer.<br></div>
<div> </div>
<div>We could always just add <span class="font" style="font-family:Menlo">Functor </span>and <span class="font" style="font-family:Menlo">Monad</span> in the standard library!<br></div>
<div> </div>
<div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo">protocol Functor {</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo"> typealias A</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo"> typealias B</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo"> typealias FB</span><br></div>
<p style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;min-height:17px;"><span class="font" style="font-family:Menlo"></span><br></p><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo"> func map(_: A -> B) -> FB</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo">}</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;min-height:17px;"> </div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo">protocol Monad: Functor {</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo"> static func pure(f: A) -> Self</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo"> func flatMap(f: A -> FB) -> FB</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo"> func >>=(x: Self, f: A -> FB) -> FB</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo">}</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;min-height:17px;"> </div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo">infix operator >>= { associativity left }</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo">func >>=<M: Monad>(x: M, f: M.A -> M.FB) -> M.FB {</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo"> return x.</span><span class="font" style="font-family:Menlo">flatMap</span><span class="font" style="font-family:Menlo">(f)</span><br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;line-height:normal;"><span class="font" style="font-family:Menlo">}</span><br></div>
<blockquote type="cite"><pre style="white-space:pre-wrap;background-color:rgb(255, 255, 255);">A few months ago I sent a pair of radars (22414579 nee 22448207 and 21961711) about Optional’s extant overloading of flatMap and how it doesn’t align with either the STL or the reasons given for the closing of both radars.
><i> This issue behaves as intended based on the following:
</i>><i></i>><i> Yes, we are aware that this overload of flatMap could be viewed as unconventional. Nevertheless, it is useful and fits the overload set in general, if you view Optional as a sequence of zero or one T. It resembles this overload, where the closure returns an arbitrary sequence:
</i>><i></i>><i> extension SequenceType {
</i>><i> public func flatMap<S : SequenceType>(transform: (Generator.Element) -> S) -> [S.Generator.Element]
</i>><i> }
</i>><i></i>><i> The type checker ensures that there is no ambiguity between the two overloads, and we don't see a reason to give one of the overloads a different name (and force users to learn it, and differentiate between the two), since conceptually the operation is the same.
</i>
If Swift wishes to regard Optionals as collections with 1 or 0 elements, then I propose that it should reflect that thinking with additions to the standard library.
Possible changes include:
1) Remove or rename Optional’s flatMap.
This would cause a bit of breaking behavior, but it’s nothing some fixits couldn’t help with.
2) Add a SequenceType instance for Optional.
This kills 2 birds with 1 stone in that, if the radar rejection is to ring true, Optional should have a SequenceType instance in the STL, and such an instance would automatically come with its own proper overloading flatMap necessitating change 1.
Over in TypeLift land we’ve already implemented what we believe the SequenceType extensions should look like (<a href="https://github.com/typelift/Swiftz/blob/master/Swiftz/OptionalExt.swift#L139-L145">https://github.com/typelift/Swiftz/blob/master/Swiftz/OptionalExt.swift#L139-L145</a> <<a href="https://github.com/typelift/Swiftz/blob/master/Swiftz/OptionalExt.swift#L139-L145">https://github.com/typelift/Swiftz/blob/master/Swiftz/OptionalExt.swift#L139-L145</a>>).<br></pre></blockquote><div> </div>
</div>
<div><img style="height:1px !important;width:1px !important;border-top-width:0px !important;border-right-width:0px !important;border-bottom-width:0px !important;border-left-width:0px !important;margin-top:0px !important;margin-bottom:0px !important;margin-right:0px !important;margin-left:0px !important;padding-top:0px !important;padding-bottom:0px !important;padding-right:0px !important;padding-left:0px !important;" border="0" height="1" width="1" alt="" src="https://www.fastmailusercontent.com/proxy/f5c9f064ba2a0e13f55a7ff066c3f15880d956ffd9189ebe5b6300fa0fa2a57c/8647470737a3f2f25723030323431303e23647e23756e64676279646e2e65647f27766f2f60756e6f35707e6d3148765176786c673171614a7d2236454230345272776e435a626267633844725a705246376a547c603b6a6d22364c6940534649403a68747955555766664a717d4848786d407368456860577c49415d41687841475a6760364675585c493731626149335056645949705369686945627e67346e6b617a7a47435779484c4863657d68634e435f496755315e6351776758584833784838617a7970776956665668674071587768577a4d2236447c453a415a77447938517261616a61644e6a69457745785668437d434779787b4a4d2232496d4153505d6661797e4176676d23344d23344/open"><br></div>
<div><u>_______________________________________________</u><br></div>
<div>swift-evolution mailing list<br></div>
<div><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br></div>
<div><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote><div> </div>
</body>
</html>