This holiday weekend has enlightened me on some important topics in functional programming. It has persuaded me to take a real look at category theory.

It all began with a need of intuition on Applicative Functors. They really are such exquisite things.

Alright, prologue aside, let's dive in. First off, let's quickly revisit `Functor`

, HKTs, their implications and how they're important. The language I will be using is Haskell *(for now)*, for obvious reasons, but will try to explain it well.

'Behind free monads, applicatives may be #1 pattern in FP, IMO'

### Revisiting Functors

A Functor is defined over types of kind `* -> *`

, or of *unary type constructors*. You've probably come across them quite a bit, as they include `List`

or `[]`

and `Maybe`

. Where types of kind `*`

are what we call **concrete types** (like `Int`

).

As an informal side note. In other languages they are quite literally similar to generic types such as

`List<T>`

,`Option<T>`

— using`Option<f64>`

, for example, in Rust. What wereallywant is higher-kinded polymorphism.

Let's take a look at the Functor typeclass (I'll explain)

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

If you're unfamiliar with haskell syntax, that's okay. This essentially means for all instances of `Functor`

it must implement a function `fmap`

that takes a function of type `(a -> b)`

and a `f a`

*(where f is the type constructor or 'context': that is a type of kind * -> * such as Maybe or List)* and returns a

`f b`

.The best way to understand this concretely for someone just starting is to take a look at `List`

or `[]`

. Remember `map`

? Its signature looks like:

```
map :: (a -> b) -> [a] -> [b]
```

Did something just click there?!? What about the `Functor`

instance for `List`

?

```
instance Functor [] where
fmap = map
```

I'm sure most of you have mapped over lists. But for completeness, An example is like

`map (*2) [1..3]`

which gives us`[2,4,6]`

That's right! Indeed `List`

is a `Functor`

, but there are in fact many types which are `Functor`

! We won't go over that here. The point is functors are things that can be mapped over.

Again, for completeness, Functors (Applicatives, and Monads) implementations must obey laws. I will omit proofs or anything rigorous here but be weary the instances should abide by the laws.

### The Applicative Meat

Time for the juicy insides. Let's take a look at the definition:

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

From our `Functor`

recap, some things here should be immediately clear. Also, for one, `Applicatives`

are indeed themselves also `Functors`

. Cool. So we see `Applicatives`

implement a `pure`

function and a `(<*>)`

(an infix function here, it's also called apply in other languages).

Is it obvious what `pure`

does here? It should be! if `f`

is some functorial context, then `a -> f a`

**lifts** `a`

into the Applicative Functor.

What about `(<*>)`

? It looks quite similar to our `fmap`

above, doesn't it? Except we notice the `f (a -> b)`

. Hmm. So it takes a `Functor`

that has a function in it and applies that function to a second `Functor`

. If you 'erase' the `f`

from the type signature, you get normal function application. Let's take a look at examples.

Holy Moly! See what's happening here? For one, In the first example `[ (2 *) ]`

is already a function in a `List`

*( List is also an Applicative Functor!)*.

**So it's applying the**

`2 *`

function *into*`[5]`

In the second example, we *lift* the binary `(*)`

function into the applicative context and then *apply* it to our applicatives.

## So what's the big deal? 🤔

First off, suppose `<$>`

is the *infix* version of `fmap`

. What if we wanted to map a function **over** a collection of Applicative Functors?

Note that

`(*)`

is a binary infix function that takes two parameters a la`2 * 2.`

Wait one second here... You're telling me I can take a function and `fmap`

it over a collection of Applicative Functors? **Inside their context**?

Note that we only use

`(*)`

here which takes 2 parameters. The real magic here is that we could use`n-ary`

functions and apply it over`n`

applicatives!

To understand how powerful this is. Think about `Future`

s, `Either`

or `Maybe`

and other very useful types. Suppose you have defined a `Router`

or `Middleware`

over a collection of routes that is an `Applicative Functor`

. How incredible and effective it would be to `fmap`

a function over **and determine or compose independent effects for all routes**.

When I realized how powerful this truly is, I was moved to order a category theory book straight away. Monads do have their shine, and for good reason! But to touch briefly on the difference, they *are dependent on the value and context a -> f b*. Applicatives are less restrictive, and have many uses

**within**all functorial types

`f a`

.Until next time.