Monads
A monad is a functor type that defines a flatMap (or bind, in other languages) function, that receives a lambda that returns the same type. Let me explain it with an example. Luckily for us, List<T> defines a flatMap function:
fun main(args: Array<String>) {
val result = listOf(1, 2, 3)
.flatMap { i ->
listOf(i * 2, i + 3)
}
.joinToString()
println(result) //2, 4, 4, 5, 6, 6
}In a map function, we just transform the List value's content, but in flatMap, we can return a new List type with less or more items, making it a lot more potent than map.
So, a generic monad will look like this (just remember that we don't have higher-kinded types):
interface Monad<C<_>>: Functor<C> { //Invalid Kotlin code
fun <A, B> flatMap(ca:C<A>, fm:(A) -> C<B>): C<B>
}Now, we can write a flatMap function for our Option type:
fun <T, R> Option<T>.flatMap(fm: (T) -> Option...