<div dir="ltr">Have been trying and thinking a lot of different functional patterns lately and came up with a lack of something. Working name for it is &quot;aliascase&quot;, though I hope we can come up with something better together. Here it is in essence:<br><div><br></div><div>Let&#39;s say we have a generic <b>typealias</b> Something and it&#39;s generic. Though I would like to extend it and make it&#39;s value be dependent on A. A passing isn&#39;t always enough (will bring example later).</div><div>







<p class="gmail-p1"><span class="gmail-s1"><b>typealias</b></span><span class="gmail-s2"> Something&lt;A&gt; = </span><span class="gmail-s3">Void</span></p><p class="gmail-p1"><span class="gmail-s3"><b>aliascase</b> Something = A? </span>where A == Int</p><p class="gmail-p1"><span class="gmail-s3"><b>aliascase</b> Something = [A.Element] </span>where A : Sequence<br></p><p class="gmail-p1">What it means is that at the end you have a default Type and special situations you want to handle differently. Considering it can work in junction with <b>associatedtype</b> constraints, <b>aliascase</b> can be constrainted as well to whatever fits into <b>associatedtype</b>.</p><p class="gmail-p1">Let&#39;s bring another more like a real life example:</p><p class="gmail-p1">protocol Monad {<br></p><p class="gmail-p1">associatedtype A</p><p class="gmail-p1">associatedtype R&lt;MA, MB&gt; : Monad where MA : Monad, MB : Monad, R.A == MB.A</p><p class="gmail-p1">func flatMap&lt;MB : Monad&gt;(_ f:(A)-&gt;MB) -&gt; R&lt;Self, MB&gt;</p><p class="gmail-p1">}</p><p class="gmail-p1"><br></p><p class="gmail-p1">Why do we need to do it in such a complicated way?? Answer: monad mixing.</p><p class="gmail-p1">Let&#39;s say we have two types Optional, Array and Future. All are monads.<br></p><p class="gmail-p1">Let&#39;s think what are the desired results of monad mixing with flatMap here:</p><p class="gmail-p1">1. Optional flatMap Optional =&gt; Optional</p><p class="gmail-p1">2. Optional flatMap Array =&gt; Array</p><p class="gmail-p1">3. Optional flatMap Future =&gt; Future<br></p><p class="gmail-p1"><br></p><p class="gmail-p1">4. Future flatMap Future =&gt; Future</p><p class="gmail-p1">5. Future flatMap Optional =&gt; Future<br></p><p class="gmail-p1">6. Future flatMap Array =&gt; Future&lt;Array&lt;A&gt;&gt;</p><p class="gmail-p1"><br></p><p class="gmail-p1">7. Array flatMap Array =&gt; Array</p><p class="gmail-p1">8. Array flatMap Optional =&gt; Array<br></p><p class="gmail-p1">9. Array flatMap Future =&gt; Future&lt;Array&lt;A&gt;&gt;</p><div><br></div><p class="gmail-p1">In most cases, we can just take the MB and make it the result of our expression (which is exactly what will be the default case for typealias). But it&#39;s not enough when talking about advanced monads.</p><p class="gmail-p1">In the case above typealiases would look like:</p><p class="gmail-p1">//In Optional.swift<br></p><p class="gmail-p1">extension Optional : Monad {</p><p class="gmail-p1">typealias A = Wrapped</p><p class="gmail-p1">typealias R&lt;MA, MB&gt; = MB //easy</p><p class="gmail-p1">}</p><p class="gmail-p1">//In Array.swift</p><p class="gmail-p1">extension Array : Monad {</p><p class="gmail-p1">typealias A = Element</p><p class="gmail-p1">typealias R&lt;MA, MB&gt; =  Array&lt;MB.A&gt; //defaults to array</p><p class="gmail-p1">}</p><p class="gmail-p1">//In Future.swift</p><p class="gmail-p1">extension Future : Monad {</p><p class="gmail-p1">typealias A = Value</p><p class="gmail-p1">typealias R&lt;MA, MB&gt; = Future&lt;MB.A&gt;</p><p class="gmail-p1"><span class="gmail-s3"><b>aliascase</b> R&lt;MA, MB&gt; = Future&lt;MB&gt; where MB : Sequence //we still fit the criteria, but enclose all multielement Monads</span><br></p><p class="gmail-p1">}</p><p class="gmail-p1">extension Array {</p><p class="gmail-p1"><b>aliascase </b>R&lt;MA, MB&gt; = Future&lt;MB&gt; where MB : FutureProtocol //we need different behaviour in this case<br></p><p class="gmail-p1">}</p><div><br></div></div><div>I know it&#39;s from quite some advanced use cases and it&#39;s not for everyday use. Though it&#39;s mandatory to get a really good middleware foundation (which IS for daily use).</div></div>