Skip to content

Instantly share code, notes, and snippets.

@blippy
Last active October 15, 2015 13:32
Show Gist options
  • Save blippy/734f5f49525123b5c42b to your computer and use it in GitHub Desktop.
Save blippy/734f5f49525123b5c42b to your computer and use it in GitHub Desktop.
Exploring Haskell monads using Either
Exploring Haskell monads using Either
Stephan Boyer explained it well why you would want to use monads:
http://www.stephanboyer.com/post/9/monads-part-1-a-design-pattern
"In each example, we had some functions which we wanted to compose,
but their type signatures were incompatible. Our functions took a
value of some type and returned a value in the corresponding monadic
type."
Let us explore this using a function "inc". This function takes a
number and adds 1 to it, with a catch: if the input value is greater
than 2, it signals an overflow. You could throw an error, for example,
but let's use the Either monad. The convention is that you use Left to
signal an error, and Right to signal a valid result. Writing this
function is easy enough:
> inc x = if x > 2 then Left "inc too high" else Right (x + 1)
If I type
> inc 0
I get
> Right 1
So far, so good. The problem is that I cannot compose it with
itself. I cannot not type
> inc (inc 0)
The types are all wrong. What am I going to do? The answer is: use
the Either's monadic bind (>>=) operator. Let us look at its type
declaration:
> (>>=) :: Monad m => m a -> (a -> m b) -> m b
Telling us what? It is telling us that (>>=) is a function that takes
two arguments: a monad, and a function, and returns another monad. In
our case, the monad is the Either monad.
The function, which we supply, takes "the thing wrapped by the first
argument", and returns a monad. This is exactly what our "inc"
function does. It takes an integer, and returns a monad.
So now, if we do
> Right 0 >>= inc
we get the answer we might expect:
> Right 1
Note that we cannot do
> 0 >>= inc
because that doesn't actually make sense. Also note that (>>=) can be
used as an infix operator - which is what we have done.
Let's experiment some more:
> Left "sucka" >>= inc
This produces:
> Left "sucka"
This makes sense. We passed garbage in (via Left), so Haskell returned
that same garbage.
We can also type
> Right 0 >>= inc >>= inc
> 2
and also gives us the "compositional form" that we were expecting.
What else?
> Right 3 >>= inc
> Left "inc too high"
I hope that is intuitively obvious what happened here. It caused our
"overflow condition".
Let's try to invoke it another way:
> Right 0 >>= inc >>= inc >>= inc >>= inc
which again gives
> Left "inc too high"
Finally, let us use some "syntactic sugar", and replace the (>>=)
notation for the more familiar "do" notation:
> v4 :: Either [Char] Integer
> v4 = do
> a <- Right 3
> b <- inc a
> return b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment