This post explores how functions in Haskell can be seen as instances of the
`Functor`, `Applicative` and `Monad` type classes, with some reflection on
the practical uses of this technique.

## Function as an instance of Functor

```
class Functor f where
fmap :: (a -> b) -> f a -> f b
```

Types parameterized by a single type can be instances of `Functor` if they
implement `fmap` in a way that follows the functor laws. The simplest example
is `Maybe`; `Maybe` is a type parameterized by a single type (also known
as *type constructor*):

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

`Maybe` is a `Functor`:

```
instance Functor Maybe where
-- fmap :: (a -> b) -> Maybe a -> Maybe b
fmap _ Nothing = Nothing
fmap g (Just x) = Just (g x)
```

So what about functions? In general, a function `(->)` is parameterized by
*two* types: `a -> b` or alternatively `(->) a b` - both `a` (the function
argument) and `b` (the function return value) can have arbitrary types for an
arbitrary function. So functions aren't a good fit for `Functor`, unless we
tweak something.

The tweak is to fix the argument type, leaving only the return type arbitrary.
This is written as `(->) a`, a type parameterized by a single type - the
return value (the argument type is fixed at `a`). Haskell type constructors
can be partially applied, same as functions. As an example, consider `Either`,
which is a type constructor parameterized by two types [1]:

```
> :kind Either
Either :: * -> * -> *
```

If we partially apply the `Either` type constructor we get another type
constructor, this time with a single type parameter:

```
> :kind Either Int
Either Int :: * -> *
```

Similarly, we can check the kind of functions:

```
> :kind (->)
(->) :: * -> * -> *
```

And of partially-applied functions:

```
> :kind ((->) Int)
((->) Int) :: * -> *
```

Before showing how `(->) a` is an instance of `Functor`, let's reformulate
it in a slightly more explicit way. Let's use `FuncWithArgA` to name the
concept of "a function with argument of type `a`". This type is parameterized
by a single type: `b`, the return value type.

So if we had to make `FuncWithArgA` an instance of `Functor`, the type of
`fmap` would be:

```
fmap :: (b -> c) -> FuncWithArgA b -> FuncWithArgA c
```

That is, we map a function `b -> c` onto `FuncWithArgA b` to produce
`FuncWithArgA c`. Now if we go back to the actual type of functions
parameterized by the return type, we get:

```
fmap :: (b -> c) -> ((->) a) b -> ((->) a) c
... or
fmap :: (b -> c) -> (a -> b) -> (a -> c)
```

So this should be the type of `fmap` for functions. One way to make this work
would be [2]:

```
instance Functor ((->) a) where
fmap g ff = \x -> g (ff x)
```

Let's follow the types: `ff` is our functor - it's a function `a -> b`. The
mapped function `g` is `b -> c`. Hence, the result of `fmap` is a function
taking `a` and returning `c`, or `a -> c`, so this matches the expected
type.

Note that `\x -> g (ff x)` is precisely the composition of `g` onto
`ff`, or `g . ff` in Haskell notation. So being extra clever, we can use
point-free notation to rewrite our `Functor` instance as:

```
instance Functor ((->) a) where
fmap = (.)
```

Now it's time for an example. Let's take the function `replicate`:

```
replicate :: Int -> a -> [a]
```

By itself, `replicate` has two arguments, so it's not a good match for our
`Functor`. But if we *partially apply* it, it will be. Say `replicate 4`.
Its type is:

```
> :t replicate 4
replicate 4 :: b -> [b]
```

`replicate 4` is a function a single parameter - a perfect fit for
`Functor`. So we can use `fmap` on it! Let's `fmap` the function `show`
on it. `show` takes any "showable" type and produces `String`. Therefore:

```
> :t fmap show (replicate 4)
fmap show (replicate 4) :: Show a => a -> String
```

Let's check the type of `fmap`:

`replicate 4`is`b -> [b]``show`is`Show a => a -> String`; in this case`[b] -> String`- So
`fmap show (replicate 4)`is`b -> String`, via function composition

We can try it on different types:

```
> fmap show (replicate 4) 5
"[5,5,5,5]"
> fmap show (replicate 4) (Just 6)
"[Just 6,Just 6,Just 6,Just 6]"
```

## Functor laws for functions

To be a proper `Functor` in Haskell, it isn't sufficient to define a
`Functor` instance that type-checks. In addition, the definition has to
satisfy the *functor laws*:

```
fmap id = id
fmap (g . h) = fmap g . fmap h
```

Explaining how the `Functor` instance for functions shown above satisfies
these laws is a great exercise in mind-bending Haskell notation, and really
stresses our grasp of types and type constructors. Let's get to it.

Two factors that make such derivations difficult to follow for beginners in
Haskell are point-free style and
currying. As an example, what does `fmap id` mean [3]?

We know that `fmap` takes two arguments: a mapped function and the functor.
`fmap id` is partially applied, or *curried* - it's another function that
already accounts for the mapped function so it only takes a single argument -
the functor. All Haskell functions are curried by default, so any multi-argument
function can be expressed as a single-argument function returning a function. In
the case of `fmap`:

```
fmap g ff = \x -> g (ff x)
... can be written as
fmap g = \ff -> \x -> g (ff x)
```

This helps, because now we can write down what `fmap id` is:

```
fmap id = \ff -> \x -> id (ff x)
... or
fmap id = \ff -> \x -> ff x
```

And this is exactly `id`, because it takes `ff` and returns a function that
takes an argument and applies `ff` to it - which is just `ff` itself. So the
first functor law holds. Let's take a look at the second one:

```
fmap (g . h) = fmap g . fmap h
```

As before, `fmap (g . h)` can be written more explicitly as:

```
fmap (g . h) ff = \x -> (g . h) (ff x)
= \x -> g (h (ff x))
```

On the other hand:

```
(fmap g . fmap h) ff
= fmap g (fmap h ff)
... by definition of "fmap h ff"
= fmap g (\x -> h (ff x))
... by definition of "fmap g ff" for ff now being (fmap h ff)
= \y -> g ((\x -> h (ff x)) y)
= \y -> g (h (ff y))
```

So the second law holds as well, meaning that our `Functor` instance for
functions is legitimate.

## Function as an instance of Applicative

Let's now move on to how functions are defined to be instances of
`Applicative`. A reminder:

```
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
```

Let's start by figuring out the types of these methods in a function instance,
using the helper `FuncWithArgA` substitute.

```
pure :: b -> FuncWithArgA b
```

Replacing `FuncWithArgA` by `(->) a`, we get:

```
pure :: b -> (a -> b)
```

A function that satisfies this type is:

```
pure = \x -> (\y -> x)
```

This is a very peculiar function, you'll notice. It takes two arguments and
returns the first, completely ignoring the second. Haskell already has such a
function in the standard library, it's called
`const`:

```
> :t const
const :: a -> b -> a
> :t const 10
const 10 :: Num a => b -> a
> (const 10) "foo"
10
> (const 10) (Just 20)
10
```

Using point-free style, `pure` is defined as:

```
pure = const
```

Now let's turn our attention to the `<*>` operator. Once again, we'll be using
`FuncWithArgA`; to make it more readable I'll rename the types in the
declaration of `<*>`, since `a` is already implied in `FuncWithArgA`:

```
(<*>) :: FuncWithArgA (b -> c) -> FuncWithArgA b -> FuncWithArgA c
.. replacing FuncWithArgA by ((->) a)
(<*>) :: (a -> (b -> c)) -> (a -> b) -> (a -> c)
```

A definition that satisfies this type is:

```
g <*> h = \x -> g x (h x)
```

The type of `g` is `a -> b -> c` and the type of `h` is `a -> b`; hence,
for a parameter of type `a`, the type of the expression is indeed `a -> c`.

To conclude, the `Applicative` instance for functions looks like this:

```
instance Applicative ((->) a) where
pure = const
g <*> h = \x -> g x (h x)
```

## Applicative laws for functions

Let's see how the instance defined satisfies the applicative laws:

```
pure id <*> x = x
pure (g x) = pure g <*> pure x
x <*> pure y = pure (\g -> g y) <*> x
x <*> (y <*> z) = (pure (.) <*> x <*> y) <*> z
```

Starting with the **first law** [4]:

```
pure id <*> x
.. by definition of pure
(\x -> (\y -> x)) id <*> x
(\y -> id) <*> x
.. by definition of <*>, with (\y -> id) for g and x for h
\z -> (\y -> id) z (x z)
.. using partial function application
\z -> id (x z)
\z -> x z
```

Which is just another way of saying `x` - a function taking a single parameter
and applying `x` to it. The first law holds! For the **second law**:

```
pure (g x)
.. by definition of pure
\y -> g x
```

Right-hand side:

```
pure g <*> pure x
.. by definition of pure
\y -> g <*> \z -> x
.. by definition of <*>
\t -> (\y -> g) t ((\z -> x) t)
\t -> (\y -> g) t x
\t -> g x
```

The **third law**, left-hand side:

```
x <*> pure y
x <*> \z -> y
.. by definition of <*>
\t -> x t ((\z -> y) t)
\t -> x t y
```

Right-hand side:

```
pure (\g -> g y) <*> x
\z -> (\g -> g y) <*> x
.. by definition of <*>
\t -> (\z -> (\g -> g y)) t (x t)
\t -> (\g -> g y) (x t)
\t -> x t y
```

The **fourth law**, left-hand side:

```
x <*> (y <*> z)
x <*> (\t -> y t (z t))
\g -> x g ((\t-> y t (z t)) g)
\g -> x g (y g (z g))
```

Right-hand side:

```
(pure (.) <*> x <*> y) <*> z
((\t -> (.) (x t)) <*> y) <*> z
(\g -> ((.) (x g)) (y g)) <*> z
\v -> x v ((y v) (z v))
```

## Function as an instance of Monad

Finally, let's see how functions are instances of `Monad`, which is defined
as:

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

For functions, starting with the `FuncWithArgA` helper:

```
return :: b -> FuncWithArgA b
```

Which, as for `Applicative` has the type:

```
b -> a -> b
```

Which is satisfied by the same function, `const`:

```
return = const
```

Now, on to `>>=`:

```
>>= :: FuncWithArgA b -> (b -> FuncWithArgA c) -> FuncWithArgA c
.. Unpacking the ``FuncWithArgA`` helper:
>>= :: (a -> b) -> (b -> (a -> c)) -> (a -> c)
>>= :: (a -> b) -> (b -> a -> c) -> (a -> c)
```

A definition that satisfies this type is:

```
g >>= h = \x -> h (g x) x
```

## Monad laws for functions

The monad laws are:

```
return x >>= f = f x
mx >>= return = mx
(mx >>= f) >>= g = mx >>= (\x -> (f x >>= g))
```

Let's start with the **first law**. Left-hand side:

```
return x = \y -> x
return x >>= f = \t -> f ((\y -> x) t) t
= \t -> f x t
```

This is equivalent to `f x`, which is in point-free style. The left-hand
side for the **second law**:

```
mx >>= return = \t -> return (mx t) t
.. by definition of return, returns the first argument whenever
applied.
= \t -> mx t
```

This can be written as just `mx` in point-free style. Finally, the **third
law**. Left-hand side:

```
(mx >> f) >>= g = (\x -> f (mx x) x) >>= g
= \t -> g ((\x -> f (mx x) x) t) t
= \t -> g (f (mx t) t) t
```

Right-hand side:

```
mx >>= (\x -> (f x >>= g)) = mx >>= (\x -> (\t -> g (f x t) t))
= \z -> (\x -> (\t -> g (f x t) t)) (mx z) z
= \z -> (\t -> g (f (mx z) t) t) z
= \z -> g (f (mx z) z) z
```

Which is equivalent, modulo the renamed bound variable.

## Real-life applicability

Now that we've persevered through the derivations, what practical uses does this technique have? I was wondering the same, so I created a Stack Overflow question that got a couple of answers. The main idea is that it lets us compose functions more succinctly, using more Haskell-y point-free style instead of explicitly creating functions with named parameters.

Consider the following example, taken from the top answer in the linked question. Here's a way to find whether a sequence is ascending:

```
> and $ (\x -> (zipWith (<=) x (drop 1 x))) [1,2,6,4]
False
> and $ (\x -> (zipWith (<=) x (drop 1 x))) [1,2,6,9]
True
```

Note that we create an explicit lambda for combining `zipWith` with its
parameters in the right way. Using applicative style, we don't need it and can
write the code more succinctly [5]:

```
> and $ (zipWith (<=) <*> drop 1) [1,2,6,4]
False
> and $ (zipWith (<=) <*> drop 1) [1,2,6,9]
True
```

Note how this achieves the same, but without the explicit lambda. `<*>` does
the functional composition for us. As an exercise, follow the types of the
sub-expressions in the `<*>` to see how this works.

Is this something you'd use in real programs? Maybe, maybe not. I think it depends on personal and project style. The first (non-applicative) option certainly looks more readable to me, but that's because I'm far from being a Haskell pro. Seasoned Haskellers may find the latter more stylistically appealing because it's more point-free, without naming parameters explicitly.

[1] | These samples show Haskell kinds
using the :kind query in ghci. In :kind output, * denotes
concrete values (also known as nullary type contructors), * -> *
denotes a single-parameter type constructor (for example the kind of
Maybe is * -> *), and so on. |

[2] | In fact, it's not just one way to make this work; it's the only way
to make this work. Functor instances for any given type are unique
in Haskell, as long as the functor laws are satisfied. This can be proved
but is outside the scope of this article. |

[3] | Note that in the equation fmap id = id, the types of id are
different on the left and on the right. On the left, fmap id takes
a functor and returns a functor, while id takes and returns the
type parameter of the functor. In other words, for Functor a,
id on the left has type a -> a while id on the right has type
Functor a -> Functor a. |

[4] | In this derivation, and throughout the post I'm making liberal use of the
power of renaming bound variables in functions. For example I may have
a function \x -> foo x on one line, and refer to it as \y -> foo
y on another line - the two are equivalent, and this renaming helps
avoid name collisions. This is called alpha conversion in Lambda calculus. |

[5] | You'll need to import Control.Applicative to get access to the
built-in applicative instance for functions. |