Recall the definition of the monad typeclass:

```
class Applicative m => Monad (m :: * -> *) where
-- methods...
```

After two articles, there are still something unsettled: what is the `Applicative`

here? To understand this one, we first have some quick review on the typeclass syntax of haskell.

## “Inheritance” of typeclass

In haskell, we can declare an “inheritance” relation over one or multiple typeclasses using type constraint. Note the “inheritance”s here are always quoted, since it just meant to make beginners with object oriented background easier to understand, and we are not really meaning the “inheritance” in the OO system.

For example, the `Ord`

typeclass

```
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(<=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(>=) :: a -> a -> Bool
max :: a -> a -> a
min :: a -> a -> a
{-# MINIMAL compare | (<=) #-}
```

Here we basically say “If we want to declare an instance of `Ord`

for type `a`

, there must be an instance for `Eq a`

”. So knowing the existance of `Eq a`

, we can define default implementation of `Ord`

using methods in `Eq`

. The whole thing works as if the `Ord`

interface is a “subclass” of `Eq`

and “inherit” all the methods in `Eq`

. And we say, “if `a`

is an `Ord`

, `a`

must be an `Eq`

”.

And the same thing apply to `Monad`

as well, so the definition above can be read as, “if `a`

is a `Monad`

, `a`

must be an `Applicative`

”

## the “inheritance chain” for `Monad`

OK then, if we look at the definition of `Applicative`

, we find an upstream of `Applicative`

as well, the `Functor`

. And we copy and paste the definition of them here.

```
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
{-# MINIMAL fmap #-}
class Functor f => Applicative (f :: * -> *) where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
{-# MINIMAL pure, ((<*>) | liftA2) #-}
```

Again we are overwhelmed by all the mysterious type signatures here. Don’t panic, the “inheritance” relation tells that that, the `Functor`

must be the most basic one, `Applicative`

extends some ability of `Functor`

, and `Monad`

is even more powerful than `Applicative`

in some way.

In the last post we introduced an idea of “context” and “value”. And as we will see, the power extended over the “inheritance chain” is the capability of manipulating the structure of “context”. And then hopefully the signature of those operation makes more sense to you.

`Functor`

for value transformation

The term `Functor`

comes from category theory. But in functional programming, functor only means one thing:

```
fmap :: Functor f => (a -> b) -> f a -> f b
```

which says with f being a functor, if we know how plain value is mapped to another(`a -> b`

), we know how values under the context are mapped (`f a -> f b`

).

For example:

```
𝝺 > :t toUpper
toUpper :: Char -> Char
𝝺 > :t fmap toUpper
fmap toUpper :: Functor f => f Char -> f Char
𝝺 > fmap toUpper "hello functor"
"HELLO FUNCTOR"
```

that is, we *lift* the transformation of values to the functor context, such as the `list`

, the `maybe`

etc. And that’s all what functor can do.

The restriction is that the context itself doesn’t change at all during the mapping, the length of list doesn’t change, `Just`

is still a `Just`

, `Nothing`

is still `Nothing`

. This makes sense because what we specified is only how plain values are mapped and know nothing abount the context at all.

And the major limitation of functor is that we can only manipulate one context at the same time, we can map only one functor object to another, but we can’t even do the following with functor.

```
-- NO WAY!
map2 :: Functor f => (a -> b -> c) -> f a -> f b -> f c
```

The rationale is that we just promise that we never change the context of functor, but two functors may have different contexts, then what is the context of the result? Functor just doesn’t know.

Careful readers must notice that this operation is provided by the `Applicative`

, which gives us some ability to “change” the contexts we have.

`Applicative`

for combining contexts

Applicative functor, or simply `Applicative`

got it name for the ability to apply function under context, that is

```
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
-- compare to
$ :: (a -> b) -> a -> b
```

When applying function under an context, the applicative should merge two contexts accordingly (`f (a -> b)`

and `f a`

). And `pure`

, the applicative version of `return`

is for generating the default context without extra effects.

After we have some ability to combining context, a lot of interesting things can happen, here we only go through the most simple and basic ones.

Note that `(<*>)`

and `liftA2`

are actually equivalent, each of them can be implemented with the other

```
class Functor f => Applicative (f :: * -> *) where
(<*>) :: f (a -> b) -> f a -> f b
(<*>) = liftA2 ($)
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f
liftA2 f fa fb = pure f <*> fa <*> fb
```

For lists, the length of the list becomes multiplication of length of two lists of parameter

```
product :: [a] -> [b] -> [(a, b)]
product = liftA2 $ \a b -> (a, b)
𝝺 > product [1,2,3] ['a', 'b', 'c']
[(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c'),(3,'a'),(3,'b'),(3,'c')]
```

For `Maybe`

s, applicative give us the ability to propagating `Nothing`

```
addIfPresent :: Maybe Int -> Maybe Int -> Maybe Int
addIfPresent = liftA2 (+)
𝝺 > addIfPresent (Just 1) (Just 2)
Just 3
𝝺 > addIfPresent (Just 1) Nothing
Nothing
```

With applicative functor, we are now able to create new context out of old contexts, but is that enough? No! With only applicative, we are not even able to implement many ordinary useful list manipulation functions like `filter`

, or sequencing operations that can go wrong (accept values and return `Maybe`

).

Why is that? Since applicative only gives us the ability to create contexts in terms of contexts and nothing to do with the value inside, observing that the context of the result is fully determined by the contexts of parameters, no matter what value they contain. So we are not able to generate contexts according to values, but functions like `filter`

have to look at values inside the context and determine the resulting context.

And you know what is coming to help, the `Monad`

.

`Monad`

for generating context

Now the intention of `(>>=)`

is completely clear for us

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

That’s exactly what we want, generating new context according to the value inside the first parameter. We presented many examples in the earlier posts and you can feel the power of monad.

Amazingly, the power of `(>>=)`

is not even a supplement of `Applicative`

and `Functor`

, we can implement `fmap`

and `<*>`

by only monad interfaces!

Let’s try it:

```
-- monad implement version of ...
fmap :: Monad m => (a -> b) -> m a -> m b
fmap f ma = ma >>= return . f
<*> :: Monad m => m (a -> b) -> m a -> m b
mf <*> ma = mf >>= \f -> ma >>= \a -> return f a
```

You may feel something uncomfortable: yes our program pass type checks if we implement `fmap`

and `(<*>)`

this way. How do we guarantee that they actually mean the same thing? In practice we can’t, of course, no one can stop you from implementing those interfaces in a strange way. But “theoretically” we can. Since these typeclasses don’t come from nowhere, their interfaces should satisfy some “laws” then can we actually call them `Functor`

, `Applicative`

, or `Monad`

. And then we can prove, different implementation of `fmap`

and `<*>`

are equivalent.

## Laws for the `Monad`

family

The laws came from the original definitions or property in maths. I won’t talk about math theory, but simply present all of them here and only get you some basic feelings.

`Functor`

law

```
-- identity
fmap id = id
-- the distributive
fmap (g . f) = fmap g . fmap f
```

Basically these laws guarantee that the value transformation relation (identity and function composition) doesn’t change after applying some context `f`

.

`Applicative`

laws

```
-- identity
pure id <*> a = a
-- associativity
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
-- homomorphism
pure f <*> pure a = pure (f a)
-- commutativity
u <*> pure a = pure ($ a) <*> u
```

Note that the applicative laws is mainly restricting the context generated by `pure`

.

Two pure context should combine to another pure context (homomorphism).

Applying pure context to another context doesn’t change that (commutativity).

The evaluation order of a sequence of contexts combination doesn’t change the resulting context (associativity law).

`Monad`

Laws

```
-- left identity
return a >>= f = f a
-- right identity
m >>= return = id
-- associativity
(m >>= f) >>= g = m >>= (\x -> f x >>= g)
```

Again, left and right identity restrict the context that `return`

can generate.

The associativity law looks a lot more complicated. But the name of it explains very well here. As long as the order of context generation is fixed, the resulting monad object should be the same.

## Conclusion

In this article we saw the increasing power of context manipulation along the “inheritance chain” of `Monad`

. I use the “context” and “value” term all along only for get you some intuition (hopefully) about what what those interfaces are doing, although it may be quite imprecise or completely nonsense in the view of mathematicians :P.

In the end we present the “laws” that the implementations should follow, although no one including compiler cannot stop you from breaking the laws, but in case of getting strange behavior of your monad, following those laws when implementing your own monad instance is considerably a good practice.

There are a lot of things we didn’t cover here. To know more about `Applicative`

or `Functor`

, this article in haskell wikibook is a good place.

Next article we will go deeper in some pratical monads in haskell monad library and introduce another important concept called the “Monad Transformer”. But before that, you may want to get yourself more familiar with the operation of basic monads and understand how they work.