* You have monads in your language:
- Optional, Future, Promise, List, Observable, etc.
* Your language's type system can't refer to them generally. This is why you don't see the word Monad in your language. If it could, you'd see: - Optional<A> implements Monad<A>
- Future<A> implements Monad<A>
- etc.
* Why is this important? It means you get to reuse the same (familiar!) machinery even when faced with a new library: - Turning a List<Future<A>> into a Future<List<A>> uses the same few standard library functions as:
- turning a Vector<Arbitrary<A>> into an Arbitrary<Vector<A>>.
* So what's the limitation of Monads? They only compose with their own concrete type: - Optional compose with Optionals.
- Futures compose with Futures.
- What if you want both, e.g. a FutureOptional<A>?
* Monad Transformers let you stack different types of Monads on top of each other, e.g: - FutureT <Optional, A>
- OptionalT <Future, A>
- EitherT <L, ReaderT<E, State <S>>, R>
* This means you can write functions which use features from any of those monads, but importantly, you can reuse any code written for only one of those monads: - An Optional<A> cannot become a Future<A>, but
- both Optional<A> and Future<A> can trivially become FutureT <Optional, A>>
- This is called lifting.