## Option Monad in Scala

September 11, 2011 Leave a comment

I’m finally succumbing to one of the clichÃ©s of functional programming interest: writing a monad tutorial. My only point here is to show the use of perhaps the simplest monad to avoid an ugly, but not uncommon pattern: nested if statements checking for null. If you’re already turned off by the word Monad, just replace it with the word “thingy” or perhaps “dingus” as you read.

Consider the java code:

static public void main(String[] args) { Object r1 = args[0]; Object r2 = f1(r1); if( null != r2 ) { Object r3 = f2(r2); if( null != r3 ) { Object r4 = f3(r3); if( null != r4 ) { System.out.println("You all everybody!"); } } } }

Clearly no thinking person should be reduced to writing such a disaster. The Option monad in Scala can let you deal with these cases with elegance:

def f1(r : AnyRef) = "you" def f2(r : AnyRef) = "all" //def f3(r : AnyRef) = "everybody" def f3(r : AnyRef) : AnyRef = null val r1 = "start" val fin = for( r2 <- Option{ f1(r1) }; r3 <- Option{ f2(r2) }; r4 <- Option{ f3(r3) } ) yield r4 fin.foreach { res => println("you all everybody") }

This code is very similar to the above Java. The for statement above is equivalent to the following syntax:

def f1(r : AnyRef) = "you" def f2(r : AnyRef) = "all" //def f3(r : AnyRef) = "everybody" def f3(r : AnyRef) : AnyRef = null val r1 = "start" Option{ f1(r1) }. flatMap( r2 => Option{ f2(r2) }). flatMap( r3 => Option{ f3(r3) }). foreach { res => println("you all everybody") }

What’s happening here? It’s simple, Option is a class that either holds Some(x) or None. When None enters your calculation at any stage, None will be the final result. Otherwise, if every step returns Some, you should complete the full calculation. None causes you to bail out. This is similar to using exceptions for control flow, or how NaNs propagate in IEEE-754 floating point arithmetic. Option in scala is pretty much identical to the Maybe Monad in Haskell. In fact, this has been implemented in Java as well.

So what exactly is a Monad? It’s pretty simple, but its name (being Greek, I guess) scares the hell out of everyone the first time they hear it. A Monad is just something that has two functions, called return and bind, which have the following rules (in scala-esque pseudo code)[see monad axioms]:

Monad.return(x).bind(y => f(y)) == f(x) m.bind(y => Monad.return(y)) == m m.bind(y => f(y)).bind(z => g(z)) == m.bind( y => f(y).bind(z => g(z)) )

In Scala, the return function is just Some(x).

Option {x}

is similiar, it returns Some(x) if x is not null, None otherwise. Bind is called flatMap, which on None returns None, on Some(x) returns Some(f(x)). None is also a monadic zero, in that when you call bind on it, like multiplication by zero, it always returns None. The analogy here in IEEE754 is if you bind with NaN the output always returns NaN (IEEE754 has embedded the Option/Maybe monad). One of the awesome things about Haskell is that they built a way to represent all sorts of things as Monads: IO, transactions, mutable memory, state-machine transitions, and many more.

Like I said, it is a total clichÃ© to write one of these posts. You can find them by the hundreds on the Web (here’s a more technical and very similar one: Monads in Scala), so, if functional programming is going to change the way we develop software, and I believe it already has and will continue to, I suppose we’ll be seeing lots more pages such as this one.