## ARTICLE

# Monads as Practical Functionality Providers

*From **Haskell in Depth** by Vitaly Bragilevsky*

*In this article we’ll discuss a few ways that you can use monads to simplify code.*

Take 40% off *Haskell in Depth* by entering **fccbragilevsky** into the discount code box at checkout at manning.com.

Haskell brings a concept of a monad to a level of practical use. In fact, we tend to think about any monad in terms of functionality it provides. Monads simplify our code significantly, they give the power of abstraction, and they guarantee the understanding of the code. In this article we’ll talk about using monads in practice. They help us implement difficult algorithms clearly and correctly, and they allow short, concise code and maintain readability and ease of support.

## A teaser: Maybe monad as a line saver

What do you think about a function returning `Maybe a`

for some type variable `a`

? Well, it’s a computation which can have no result at all. The next question: what if you’ve several such computations and your task is to produce overall result from them? In general, there are two basic strategies:

- if you need both results to produce final one and one of the computations gives you
`Nothing`

then you answer with`Nothing`

; - if it’s enough for you to get one result of the two then you stick with one which isn’t Nothing.

The choice of the right strategy clearly depends on your goals but Haskell gives you abstractions for both: the first strategy is implemented by monadic bind `>>=`

for `Maybe`

monad and the second one—by monoid operation over `Maybe`

values.

Imagine that you’ve two associative lists: one with person name and phone number pairs, and another with phone number and corresponding location pairs. How do you find location by the persons’ name? Clearly this scenario demands for the first strategy, because we can’t proceed without getting phone number first and we’re forced to return `Nothing`

.

Let’s implement this scenario in code. We’ve the following types:

`type Name = String type Phone = String type Location = String type PhoneNumbers = [(Name, Phone)] type Locations = [(Phone, Location)]`

We also have function `lookup`

from `Prelude`

which is clearly a computation in `Maybe`

monad:

`lookup :: Eq a => a -> [(a, b)] -> Maybe b`

Now we can implement searching for location via `>>=`

for `Maybe a`

:

`locByName :: PhoneNumbers -> Locations -> Name -> Maybe Location locByName pnumbers locs name = lookup name pnumbers >>= flip lookup locs`

Although we’ve had to `flip`

arguments for `lookup`

to get a function suitable for monadic binding (`flip lookup locs`

subexpression has type `Phone → Maybe Location`

) the implementation looks quite concise and guarantees that we’ll get Just somelocation provided by two successful lookup calls.

An implementation without monadic bind looks more tedious:

`locByName' :: PhoneNumbers -> Locations -> Name -> Maybe Location locByName' pnumbers locs name = case lookup name pnumbers of Just number -> lookup number locs`

Nothing -> Nothing

If you look at the implementation of `>>=`

for `Maybe`

you’ll see the code with pattern matching over `Maybe a`

value to the left of `>>=`

:

**instance** **Monad** **Maybe** **where** (**Just** x) >>= k = k x

**Nothing** >>= **_** = **Nothing** -- ...

We’ve saved a little of typing by reusing `>>=`

. This is all about it: we use monads for functionality and convenience they provide. The same idea works for `Functor`

and `Applicative`

too as we normally try to use the functionality they provide whenever it’s sufficient for our goals.

For another example, let’s suppose you’re given a `String`

representing number, something like `"21"`

. How do you double it? You must take special care here: what if `String`

is incorrect and doesn’t represent any number? Well, we can use `readMay`

from `Safe`

module:

`readMay :: Read a => String -> Maybe a`

You don’t want to multiply `Nothing`

by 2 or you’ll cause the `Functor`

to not work:

`doubleStrNumber :: (Num a, Read a) => String -> Maybe a doubleStrNumber s = (*2) <$> readMay s`

It works as expected:

`ghci> doubleStrNumber "21" Just 42`

ghci> doubleStrNumber "yy" Nothing

If you’ve two `String`

-represented numbers and need to compute their sum, then it’s a job for `Applicative`

:

`plusStrNumbers :: (Num a, Read a) => String -> String -> Maybe a plusStrNumbers s1 s2 = (+) <$> readMay s1 <*> readMay s2`

And it also works as a charm:

`ghci> plusStrNumbers "3" "5" Just 8`

ghci> plusStrNumbers "3" "x" Nothing

If you want to see more, check out the book on Manning’s liveBook platform here.