The Option Monade

sealed class Option<out A> {
    object None : Option<Nothing>()
    data class Some<out A>(val value: A) : Option<A>()

    fun <B> flatMap(f: (A) -> Option<B>): Option<B> =
            when (this) {
                is None -> this 
                is Some -> f(value)
            }
}

With functions like

fun squared(a: Double) = Option.Some(a * a)

fun reciprocal(a: Double) = when {       
    a == 0.0 -> Option.None
    else -> Option.Some(1.0 / a)
}

fun sqareRoot(a: Double) = when {       
    a < 0.0 -> Option.None
    else -> Option.Some(Math.sqrt(a))
}

you can write

fun main(args: Array<String>) {
   println(Option.Some(3.0).flatMap(::reciprocal).flatMap(::squared))
   println(Option.Some(0.0).flatMap(::reciprocal).flatMap(::squared))
}

and the result is

> Some(value=0.1111111111111111)
> monade.Option$None@2626b418
Advertisements