In the last post we went through some most basic concepts of Monad in haskell, and sequencing simple IO operations with `do`

notation. In this article I would present some other simple and common Monad instances and examples like `List`

, `Maybe`

and `Either`

.

## Monad as the Computation Context

in the last article we introduce one (or two) method of Monad, the `(>>=)`

(bind) operation. Actually there is a simple but equally important method of Monad, namely `return`

,

```
class Applicative m => Monad (m :: * -> *) where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
-- ... other methods ...
```

which constructs a “trivial” monad object with certain value. Note that different from many imperative languages, `return`

is not a keyword in haskell but a ordinary function. But its usage expains its name very well, as we will see.

Now we take one step forward, we see monad as a context for value computation or transformation and take some extra *effects*. With this view, `return`

is a way that *lifts* an value from our world to certain monad context. It’s not trivial as it looks like at all.

And about (»=), it says that given a monad object of type `a`

, and a way to construct a context of `b`

with some plain value `a`

, the monad can somehow retrieve the value in the original monad and feeds it into the function, usually during this process, some extra operation featured by the monad would be performed, like `IO`

operation.

We will talk about the “context” and “value” concepts in more detail in the next article.

## Examples

### List

List Monad emphasize less on sequencing some operation but more on the “context” since it’s easier to understand this way.

The list context represents 0 or more value of certain type. The `return`

operation is simple, which simply construct a singleton list with that value. For (»=), since every single value in the context (should) produce a new context, the result becomes the concatenation of every new context produced, that is it allow us to extend (or shrink) the original list on demand, according to the value.

Let’s look at a trivial example first:

```
duplicate :: a -> [a]
duplicate a = [a, a]
copyEach :: [a] -> [a]
copyEach xs = xs >>= duplicate
```

if we test it in GHCi

```
𝝺 > copyEach [1,2,3,4]
[1,1,2,2,3,3,4,4]
```

This looks boring. The following may looks more interesting and useful. We can use (»=) to implement `filter`

,

```
filter :: (a -> Bool) -> [a] -> [a]
```

which says we leave all values that satisfy the predicate (a -> Bool), and filter out those that don’t. We *can* define the filter in this way

```
filter p xs = do
x <- xs
if p x then return x else []
```

Note that in this do notation, what we extract as `x`

is **every value** in the list context. So for every value, if `p x`

returns `True`

, we preserve it, otherwise in the new context we just throw it away.

The list monad is useful also when we are processing more than one list, such as computing the Cartesian Product of two list.

```
product :: [a] -> [b] -> [(a, b)]
product xs ys = do
x <- xs
y <- ys
return (x, y)
```

It looks simple and clean, but also interesting to think about how it exactly works.

#### List Comprehension

Since list processing is quite common in haskell, haskell provides an syntactic sugar for the monadic operation on list.

The filter and product can be defined as :

```
filter p xs = [x | x <- xs, p x]
product xs ys = [(x, y) | x <- xs, y <- ys]
```

More detailed syntax of list comprehension can be found on haskell wiki

`Maybe`

#### motivation

the `Maybe`

type is a super useful tool for type safe error handling. It’s defined as:

```
data Maybe a = Just a | Nothing
```

which basically say a maybe object may or may not has a value of its type parameter. When we want to define some function that can go wrong, we make the function return an `Maybe`

object and everyone knows that the function returns `Nothing`

as a sign of error.

But something tricky remains, what do we do after getting a “maybe”. If there’s only one function returns maybe, we’re fine, we simply pattern match it and divide the control flow. But considering the following senario.

```
-- Many steps of the computation can go wrong...
actionA :: A -> Maybe B
actionB :: B -> Maybe C
actionC :: C -> Maybe D
-- Then how do we implement the action that combine actionA, B, C together
action :: A -> Maybe D
-- OK let's try pattern matching...
action a = case actionA a of
Just b -> case actionB b of
Just c -> case actionC c of
Just d -> Just d
Nothing -> Nothing
Nothing -> Nothing
Nothing -> Nothing
```

The senario is quite common in real life, the steps of the large computation can go wrong individually. And as we see, pattern matching along the way is **definitely not** what we want here. But if we recognize the pattern of this pattern matching process, we find something familiar again.

#### the monad

If we have a function that do all pattern matching for us, that would be good.

```
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
```

And look at the pattern of the pattern matching above, we observe that when we want to convert some `Maybe`

to another `Maybe`

, the only way we success is all the computation success, if any of the middle steps goes wrong, we shutdown the whole process since further computation cannot be done.

So what monad can do for us is that

```
ma >>= f = case ma of
Nothing -> Nothing
Just a -> f a
```

And when chaining things together, things go extremely fluent and clean here

```
actionRefined :: A -> Maybe D
actionRefined a = do
b <- actionA a
c <- actionB b
actionC c
```

It seems unbelievable, but it perfectly makes sense once you figure it out. Just note that if actionA “goes wrong” and fail to produce some “b” here, actionB and the following would fail to continue as well.

What’s extraordinary for maybe monad is that, when we are sequencing operation that may goes wrong, we can only care about the logic of going the right way, and let maybe monad handle the rest of that, shut the computation down at some correct time.

`Maybe`

monad, like most kind of monads, emphasizes on sequencing operations within some context. We lift ordinary value to a context where error may happen, and every step of computation, the `Maybe`

monad checks the presentation of error and decide whether the computation goes on.

`Either`

But, despite the “perfectness” of `Maybe`

, something is still unsatisfying. When an operation of a sequence of small operation returns `Nothing`

, we have no way to know which step of the operation goes wrong outside, which maybe crucial in some senario, we want to produce some reasonable error messages for example.

The reason why this awkward thing happens is that, when error come out, the only way we can represent the error is `Nothing`

and nothing else. If we can say more about `Nothing`

, that would be good, and here’s when `Either`

can help.

```
data Either a b = Left a | Right b
```

Conventionally, we use `Right`

to denote the success case, and `Left`

to denote the error case. We can choose `String`

or whatever type we want to represent errors.

You may wonder how `Either`

can be a monad since it has literally two type parameters while monad requires the type has only one. The solution is we can fix the first parameter and make `Either`

and the first paramter together a monad instance, and it is defined in this way:

```
instance Monad (Either e) where
-- implementations...
```

And that tells us, basically if we want to handle error with `Either`

in a monadic way, we have to fix the type for the “error” for a period of time (throughout the error handling code at least).

There’s really nothing new for either monad compares to maybe monad, both monads are for functional style error handling. The last thing we should know about either monad is that, we said either monad can preserve **some** information about errors, it **only preserves the first error information it encounters**. It makes sense because after the first error, the rest of computation never continues just as what maybe monad do.

But either is still not perfect, if we are doing some operations that don’t rely on the result of others, we can still preserve **only one** error message. And if we want to provide the functionality that can notify the receiver of the result all the error happens in a bunch of operations, new structure or design would be required.

#### reflection about error handling

At last we settle some subtle questions.

The first is the comparison of maybe and either monad, if either can always preserve more information than maybe do, why would we use maybe at all? The thing is that in many situations where error occurs, we can instantly know when errors should occur, as following examples

```
div :: (Num n) => n -> n -> Maybe n
index :: Int -> [a] -> Maybe a
```

When we are dividing some numbers and goes wrong, we know that in 90% of the cases that’s because the divisor is zero. Similarly, when we index through an array like structure and an `Nothing`

is returned, we know it’s probably an out-of-range error. And there are many cases like these, if just `Nothing`

itself is perfectly makes sense, why would we bother to look at those error messages or reasons.

The second question is why we use the horrifying monad to handle exceptions and errors, why can’t we just throwing exception around and catch them at appropriate places like many imperative languages. This is techniquely not a topic about monad but something more higher level at the “ideas of functional programming”. I don’t want to talk very much about this right here, in short, not allowing function type signature to lie should be a good thing most of the time.

## Conclusion

We walk through some most basic and useful monads in haskell in this article, and rest of the thing for you just look at the documentation yourself and try to play with those monads in your codes. Although monads in this article themselves are not so complicated, but when “stacked” with other monads as would be introduced in future article, it will be a different thing, so it’s important to master these simple things before going further.

In the next article, I will **try to** demystify what `Applicative`

in the `Monad`

definition and all other related things like `Functor`

. I can’t explain all the math and theoretical things about where are those terminologies come from, but hopefully give you a most basic idea about what those things are in a functional programming language.