What is wrong with flatMap returning an Optional? Like Scala does.<br><br>On Sunday, 31 January 2016, Joseph Lord via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Currently there are three types of operator: prefix, infix and postfix and most of the Swift operations can be defined using these and implemented for additional types and they cover most use cases but there are features in the Swift language which cannot be replicated and customised with these.<br>
<br>
In particular there is the optional chaining use of `?` for which I can see no way of producing customised versions of or adapting to types other than optionals (e.g. custom Either types or other monadic types).<br>
<br>
I’m not sure about the feasibility of this change or what knockon effects might be. This is meant as exploratory suggestion that may not reach proposal stage.<br>
<br>
Would be interested to know:<br>
1) If this is feasible.<br>
2) If it is interesting to people.<br>
3) What if anything should be possible for l-values (optional chaining works on them but what should be possible.<br>
4) Any other good alternatives.<br>
<br>
I picture that the chaining operator function would be called with the left hand side value and could be required to return a value of a type such as this ChainValueResult:<br>
<br>
enum ChainValueResult<A,C,D> {<br>
case continue(A, C->D),<br>
case stop(D)<br>
}<br>
<br>
The logic then applied to this enum would be in case of continue to apply the C->D function to the result of continuing the chain which is applied to the A value. In the case of stop it is to simply return the value of type D.<br>
<br>
I have used this enum in the draft code below. Please note that the code below doesn't compile and that if really being used the inference system would need to account for the return type of the ongoing chain.<br>
<br>
Use case 1 - Custom optional chaining behaviour<br>
<br>
The particular thing that I would like use this for is to make a custom asserting variant of the optional chaining operator. I already do this with nil coalescing (it is currently the only custom operator in my code) but a shorthand for this would be good:<br>
<br>
assert(foo != nil)<br>
foo?.bar()<br>
<br>
I would only want to do:<br>
<br>
foo±.bar()<br>
<br>
func ± <A, C>(lhs: A?)->ChainValueResult<A, C->C? ,C?> {<br>
if let lhs = lhs {<br>
return .continue(lhs, { $0 })<br>
} else {<br>
assertionFailure()<br>
return .stop(nil)<br>
}<br>
}<br>
<br>
Use case 2 - Chaining on custom types<br>
<br>
And this especially may not be feasible and I may be out of my depth describing the requirement but it feels like a more general case so at least worth airing):<br>
<br>
It would be good for code like the following to be possible (hopefully with a little more type inference).<br>
<br>
let c:Either<Int, Error> = Either<String, Error>(.Left(“boo"))^^.count<br>
<br>
Now the user’s definition of the operator would probably have to look something like this:<br>
<br>
func ^^<A,B, C>(lhs: Either<A,B>)->(ChainValueResult<A, C, Either<C,B>> {<br>
switch lhs {<br>
case .Left(let a):<br>
return .continue(a, { Either<C,B>(.Left($0) })<br>
case .Right(let b):<br>
return .stop( Either<C, B>(.Right(b))<br>
}<br>
}<br>
<br>
I couldn't find any significant discussion of optional chaining in the mailing list so far.<br>
<br>
Joseph<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a>swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote><br><br>-- <br> -- Howard.<br><br>