Skip main navigation

Example: the Maybe monad

The Maybe Monad is a simple but very useful example of a monadic computation
© University of Glasgow
  • We’ve already seen the Maybe type. Let’s look at the Maybe monad, which makes using the Maybe type a lot easier.

The Maybe type constructor

You already know the definition of the Maybe type:
 data Maybe a = Just a | Nothing

Example use of Maybe: Safe head and tail

The head and tail functions from the Prelude are not safe in the sense that they fail when called on an empty list. We can define safe versions using Maybe:
 myHead :: [a] -> Maybe a
myHead [] = Nothing
myHead (x:xs) = Just x

myTail :: [a] -> Maybe [a]
myTail [] = Nothing
myTail (x:xs) = Just xs

Monad instance of Maybe

Now we can make Maybe an instance of the Monad type class, simply by providing the appropriate definitions for return, bind, then and fail:
 import Control.Monad

instance Monad Maybe where
return = Just
Nothing >>= f = Nothing
(Just x) >>= f = f x
fail _ = Nothing
There are a few additional functions defined in the MonadPlus type class:
 instance MonadPlus Maybe where
mzero = Nothing
Nothing `mplus` x = x
x `mplus` _ = x
That’s it, we now have a Maybe monad!
Note: for users of ghc 7.10 and higher, we need to do a little bit more work.

Explicit Maybe versus the Maybe Monad

Let’s see what this monad gives us:

A computation using explicit Maybe

 foo :: [a] -> Maybe a
foo xs =
case myTail xs of
Nothing -> Nothing
Just a -> case myTail a of
Nothing -> Nothing
Just b -> myHead b
To combine computations that use the Maybe type, we need explicit case expressions to pattern match against the type.

A computation using the Maybe monad

Let’s write this computation using the Maybe monad, first using the >>= operator:
 bar :: [a] -> Maybe a
bar xs =
myTail xs >>=
(\a -> myTail a >>=
(\b -> myHead b))
Now let’s change the line breaks and indentation a bit to make it look nicer:
 bar2 :: [a] -> Maybe a
bar2 xs =
myTail xs >>= (\a ->
myTail a >>= (\b ->
myHead b))
Thanks to the associativity law, we can also remove unnecessary parentheses:
 bar3 :: [a] -> Maybe a
bar3 xs =
myTail xs >>= \a ->
myTail a >>= \b ->
myHead b
This is already a lot cleaner, but finally we can use the do-notation:
 bar3 :: [a] -> Maybe a
bar3 xs = do
a <- myTail xs
b <- myTail a
myHead b
Clearly, the final monadic code is a lot more readable than the original non-monadic code.

Example: Reduction of bar [5,6]

 bar [5,6]

-- > substitute [5,6] for xs in definition of bar

myTail [5,6] >>=
(\a -> myTail a >>=
(\b -> myHead b))

-- > def. myTail

Just [6] >>=
(\a -> myTail a >>=
(\b -> myHead b))

-- > def.2 of (>>=)

(\a -> myTail a >>=
(\b -> myHead b))
[6]
-- > beta reduction, substitute [6] for a

myTail [6] >>= (\b -> myHead b)

-- > reduce myTail

Just [] >>= (\b -> myHead b)

-- > def.2 of (>>=)

(\b -> myHead b) []

-- > beta reduction, substitute [] for b

myHead []

-- > def.1 myHead

Nothing

Example: Reduction of bar [5,6,7]

 bar [5,6,7]

-- > substitute [5,6,7] for xs in definition of bar

myTail [5,6,7] >>=
(\a -> myTail a >>=
(\b -> myHead b))

-- > def. myTail

Just [6,7] >>=
(\a -> myTail a >>=
(\b -> myHead b))

-- > def.2 of (>>=)

(\a -> myTail a >>=
(\b -> myHead b))
[6,7]
-- > beta reduction, substitute [6,7] for a

myTail [6,7] >>= (\b -> myHead b)

-- > reduce myTail

Just [7] >>= (\b -> myHead b)

-- > def.2 of (>>=)

(\b -> myHead b) [7]

-- > beta reduction, substitute [7] for b

myHead [7]

-- > def myHead

Just 7
© University of Glasgow
This article is from the free online

Functional Programming in Haskell: Supercharge Your Coding

Created by
FutureLearn - Learning For Life

Our purpose is to transform access to education.

We offer a diverse selection of courses from leading universities and cultural institutions from around the world. These are delivered one step at a time, and are accessible on mobile, tablet and desktop, so you can fit learning around your life.

We believe learning should be an enjoyable, social experience, so our courses offer the opportunity to discuss what you’re learning with others as you go, helping you make fresh discoveries and form new ideas.
You can unlock new opportunities with unlimited access to hundreds of online short courses for a year by subscribing to our Unlimited package. Build your knowledge with top universities and organisations.

Learn more about how FutureLearn is transforming access to education