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 "aliascase",

though I hope we can come up with something better together. Here it is in

essence:

Let's say we have a generic *typealias* Something and it's generic. Though

I would like to extend it and make it's value be dependent on A. A passing

isn't always enough (will bring example later).

*typealias* Something<A> = Void

*aliascase* Something = A? where A == Int

*aliascase* Something = [A.Element] where A : Sequence

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 *associatedtype* constraints, *aliascase* can be constrainted

as well to whatever fits into *associatedtype*.

Let's bring another more like a real life example:

protocol Monad {

associatedtype A

associatedtype R<MA, MB> : Monad where MA : Monad, MB : Monad, R.A == MB.A

func flatMap<MB : Monad>(_ f:(A)->MB) -> R<Self, MB>

}

Why do we need to do it in such a complicated way?? Answer: monad mixing.

Let's say we have two types Optional, Array and Future. All are monads.

Let's think what are the desired results of monad mixing with flatMap here:

1. Optional flatMap Optional => Optional

2. Optional flatMap Array => Array

3. Optional flatMap Future => Future

4. Future flatMap Future => Future

5. Future flatMap Optional => Future

6. Future flatMap Array => Future<Array<A>>

7. Array flatMap Array => Array

8. Array flatMap Optional => Array

9. Array flatMap Future => Future<Array<A>>

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's not enough when talking about advanced monads.

In the case above typealiases would look like:

//In Optional.swift

extension Optional : Monad {

typealias A = Wrapped

typealias R<MA, MB> = MB //easy

}

//In Array.swift

extension Array : Monad {

typealias A = Element

typealias R<MA, MB> = Array<MB.A> //defaults to array

}

//In Future.swift

extension Future : Monad {

typealias A = Value

typealias R<MA, MB> = Future<MB.A>

*aliascase* R<MA, MB> = Future<MB> where MB : Sequence //we still fit the

criteria, but enclose all multielement Monads

}

extension Array {

*aliascase *R<MA, MB> = Future<MB> where MB : FutureProtocol //we need

different behaviour in this case

}

I know it's from quite some advanced use cases and it's not for everyday

use. Though it's mandatory to get a really good middleware foundation

(which IS for daily use).