<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 12 Mar 2017, at 14:32, Matthew Johnson <<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class="">This is a really important feature IMO, but as others have pointed out it basically amounts to higher-kinded types. I would love to be wrong about this but I am reasonably sure this is out of scope for Swift 4 (otherwise I would be working on a proposal already).<br class=""><br class="">Sent from my iPad</div><div class=""><br class=""></div></div></div></blockquote><div><br class=""></div><div>I’m not an expert on this stuff, but are they still higher-kinded types if we don’t express a relationship between Self and the associated type? I don’t think it’s quite the same conceptual leap as HKT.</div><div><br class=""></div><div>Consider that every associated type must be backed by a typealias (explicit or inferred) in the conforming type. We can already have generic typealiases. This would be a more targeted thing which required those associatedtype-implementing-typealiases to contain generic parameters. It would also extend the constraints from SE-0142 to allow constraints to refer to those parameters and bind them to other associated types.</div><div><br class=""></div><div>The workaround is basically to erase and dynamic-cast your way out:</div><div><br class=""></div><div><span style="font-family: Courier;" class=""> //NOTE: dynamic type of ScanPromise.Result *must* be same as closure result. No static enforcement though :(</span></div><div><span style="font-family: Courier;" class=""><br class=""></span></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div><div class=""><font face="Courier" class="">extension Scanner where ScanPromise.Result == Any? {</font></div></div></div><div><div><div class=""><font face="Courier" class=""> func scan<T>(from f: Offset, until u: (Offset, Item) -> T?) -> T? {</font></div></div></div><div><div><div class=""><font face="Courier" class=""> return withoutActuallyEscaping(u) { _u -> T? in</font></div></div></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div><div class=""><font face="Courier" class=""> return promiseScan(from: f, until: _u).await() as? T // downcast from Any? to T?</font></div></div></div><div><div><div class=""><font face="Courier" class=""> }</font></div></div></div><div><div><div class=""><font face="Courier" class=""> }</font></div></div></div><div><div><div class=""><font face="Courier" class="">}</font></div></div></div><div><div><div class=""><font face="Courier" class=""><br class=""></font></div></div></div><div><div><div class=""><font face="Courier" class="">class MyPromise<R>: Promise {</font></div></div></div><div><div><div class=""><font face="Courier" class=""> typealias Result = R?</font></div></div></div><div><div><div class=""><font face="Courier" class=""> let offset: Offset</font></div></div></div><div><div><div class=""><font face="Courier" class=""> let block: (Offset, Item) -> R?</font></div></div></div><div><div><div class=""><font face="Courier" class="">}</font></div></div></div><div><div><div class=""><font face="Courier" class=""><br class=""></font></div></div></div><div><div><div class=""><font face="Courier" class="">class MyScanner: Scanner {</font></div></div></div><div><div><div class=""><font face="Courier" class=""> typealias ScanPromise = MyPromise<Any> // want this to be “typealias ScanPromise<X> = MyPromise<X>"</font></div></div></div><div><div><div class=""><font face="Courier" class=""><br class=""></font></div></div></div><div><div><div class=""><font face="Courier" class=""> func promiseScan<T>(from: Offset, until: @escaping (Offset, Item) -> T?) -> ScanPromise {</font></div></div></div><div><div><div class=""><font face="Courier" class=""> return MyPromise(offset: from, block: until) // upcast from T? to Any?</font></div></div></div><div><div><div class=""><font face="Courier" class=""> }</font></div></div></div><div><div><div class=""><font face="Courier" class="">}</font></div></div></div></blockquote><div><div><br class=""></div><div>- Karl</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class="">On Mar 11, 2017, at 11:49 PM, Karl Wagner via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class="">I have a model like this:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class="">protocol Promise {</font></div><div class=""><font face="Courier" class=""> associatedtype Result</font></div><div class=""><font face="Courier" class="">}</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">protocol Scanner {</font></div><div class=""><font face="Courier" class=""> associatedtype ScanPromise: Promise</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class=""> func promiseScan<T>(from: Offset, until: (Offset, Item) -> T?) -> ScanPromise // where Result == T?</font></div><div class=""><font face="Courier" class="">}</font></div></blockquote><div class=""><br class=""></div><div class="">The thing that I’m trying to express is: whichever type implements the associated type ‘ScanPromise’ must be generic, and that parameter must be its result (i.e. something it got as a result of calling the “until” closure).</div><div class=""><br class=""></div><div class="">Even with SE-0142, this kind of constraint would not be possible. What I would like to write is something like this:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Courier" class="">protocol Promise {</font></div><div class=""><font face="Courier" class=""> associatedtype Result</font></div><div class=""><font face="Courier" class="">}</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">protocol Scanner {</font></div><div class=""><font face="Courier" class=""> associatedtype ScanPromise<T>: Promise // now generic. [SE-0142]: where Result == T</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class=""> func promiseScan<T>(from: Offset, until: (Offset, Item) -> T?) -> ScanPromise<T></font></div><div class=""><font face="Courier" class="">}</font></div></div><div class=""><br class=""></div><div class="">Thoughts?</div><div class=""><br class=""></div><div class="">- Karl</div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></div></blockquote></div><br class=""></body></html>