## Motivation

`Functor` solves the problem of mapping regular one-parameter functions into a sub-category, but that's not easy for functions with more than one parameters.

Let's consider a function with two parameters `f :: a -> b -> c`, which can also read as `a -> (b -> c)`. Applying `fmap` on `f`, we will get `fmap f :: m a -> m (b -> c)`. There's still some distance from what we want: `f' :: m a -> m b -> m c`. To get `f'`, we need a transform from `m (b -> c)` to `m b -> m c`. Here we denote it as `<*> :: m （b -> c) -> m b -> m c`. We will later show that such transform is universal for functions with more parameters.

Now consider a function with three parameters `f :: a -> b -> c -> d`. We are going to transform it into a wrapped-value version, with the help of `fmap` and `<*>`.

``````f :: a -> b -> c -> d

(fmap f) :: m a -> m (b -> (c -> d))

\a_ b_ -> (fmap f a_) <*> b_
:: m a -> m b -> m (c -> d)

\a_ b_ c_ -> ((fmap f a_) <*> b_) <*> c_
:: m a -> m b -> m c -> (m d)
``````

Here `\a_ b_ c_ -> ((fmap f a_) <*> b_) <*> c_` is in the desired type. For most of the time, applying parameters directly is actually what we want, instead of the function itself, so the code could simply be written as `((fmap f a) <*> b) <*> c`, where `a`, `b` and `c` are wrapped values. Parenthesis could be omitted if precedences are set properly, which leads to a neat and easy-to-read form:

``````f `fmap` a <*> b <*> c
``````

In haskell, `fmap` has an infix name `<\$>`. So finally we get: `f <\$> a <*> b <*> c`.

## Applicative

Haskell pre-defined a type class `Applicative`, which captures the pattern `<*>`. Any type that implements `Applicative` works well with `<\$>` and `<*>`.

``````class Functor f => Applicative (f :: * -> *) where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
GHC.Base.liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
``````

Note that an `Applicative` is also a `Functor`. Apart from `<*>`, there are some other helper functions or operators in `Applicative`.

`pure` is equivalent to the default value constructor of `f`, e.g. `(:[])` for `List` or `Just` for `Maybe`. This may be handful when lifting an unwrapped value to a wrapped one.

`liftA2` transforms a binary operator to the corresponding version. The function exists as binary operators would be frequently passed among high-order functions.

`*>` takes two wrapped parameters and simply returns the second one, which sequence up two wrapped values. This is quite useful for `Applicative` with action semantics, such as `IO`. In fact, it's so useful that Haskell introduces a syntax sugar for it, known as the `do-notation`. Particularly:

``````do
putStrLn "1"
putStrLn "2"
``````

is equivalent to

``````putStrLn "1" *> putStrLn "2"
``````

`<*` is similar. Both will be reviewed while studying Monad.