# My notes on Functor, Applicative and Monad

## Functor

This post provides vivid explanation for Functors in Haskell. However, I still find it confusing why we have functors in Haskell.

In order to really understand functors, we must explore the origin of this concept. According to wikipedia, “a functor is a type of mapping between categories”, but “mapping” relation isn’t very obvious to me.

The signature of `fmap`

is:

1 | fmap :: (a->b) -> f a -> f b |

If we rewrite it to be (the parentheses was implicit before):

1 | fmap :: (a->b) -> (f a -> f b) |

we could interpret that `fmap`

takes one argument, one function with type `a->b`

, and convert it into another function on new types (new domain), ```
f a
-> f b
```

. Now the “mapping” referred in the definition becomes explicit.

Intuitively, I understand types in `Functor`

class as containers, that could hold some value.

## Monad

All monads in Haskell are type constructors, but not all type constructors are monads. As we will see, monads have to be type constructors for which specific operations are defined and for which specific “monad laws” hold.

`return`

and `>>=`

(bind) are the two passages connecting the pure and impure worlds. Looking at the type of `>>=`

:

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

We can be sure there’s some “unpacking” done in the middle, and how this “unpack” happens is defined by each instance of “Monad” type class.

Many people mistakenly believe that the only reason for having monads in Haskell is to handle non-functional computations i.e. ones that do (file or terminal) I/O, alter global variables, etc. And yet, here I showed you a monadic computation which can be done perfectly well without monads. In this case, monads are not essential; they’re just very convenient. And that’s why I said that even though the original reason for adding monads to Haskell had to do with dealing with inherently non-functional kinds of computations (like computations involving I/O), they turned out to have a far greater applicability. That’s why they’re neat.

```
f :: Int -> Maybe Int
f x = if x `mod` 2 == 0 then Nothing else Just (2 * x)
g :: Int -> Maybe Int
g x = if x `mod` 3 == 0 then Nothing else Just (3 * x)
h :: Int -> Maybe Int
h x = if x `mod` 5 == 0 then Nothing else Just (5 * x)
k = f >=> g >=> h
k x = case f x of
Nothing -> Nothing
Just y -> case g y of
Nothing -> Nothing
Just z -> h z
```

Given `(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)`

, it’s obvious how it could be constructed using `bind`

above.

Since `Monad`

is a subclass of `Functor`

, it could be understood as containers, where sequencing operations are defined.

## Applicative vs Monad

`Applicative`

is something between `Functor`

and `Monad`

; it’s a subclass of `Functor`

, and the parent class of `Monad`

. For `Applicative`

types,
sequencing operations are defined as well, so it’s a bit sutble to pinpoint the difference between `Applicative`

and `Monad`

.

The following example illustrates that `Monad`

support “short-circus” while `Applicative`

would do the function application anyway.

```
import Control.Applicative (pure, (<*>))
monad_f :: Int -> Maybe Int
monad_f x = return x
monad_f' :: Int -> Maybe Int
monad_f' x = undefined
applicative_f :: Maybe (Int -> Int)
applicative_f = return id
applicative_f' :: Maybe (Int -> Int)
applicative_f' = undefined
x :: Maybe Int
x = Nothing
main = do
print $ x >>= monad_f
print $ x >>= monad_f'
print $ applicative_f <*> x
print $ applicative_f' <*> x
```

The output is:

```
Nothing
Nothing
Nothing
test.hs: Prelude.undefined
```