> ## Content Index
> Fetch the complete content index at: https://jahans.blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# Encounter with Applicative Functors
- URL: https://jahans.blog/re-encounter-with-applicative-functors/
- Published: 2017-12-29T03:39:50.000Z
- Updated: 2020-01-11T07:17:17.000Z
- Author: Jahan Addison
- Tags: #Import 2023-06-19 03:22, #Import 2025-07-14 00:52, #Import 2026-09-13 01:33

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)](https://github.com/rust-lang/rfcs/pull/1598?ref=jahans.blog)*, 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 we *really* want is higher-kinded polymorphism.

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

```haskell
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:

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

```

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

```haskell
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](https://i.imgur.com/3k4eBKj.png?ref=jahans.blog).

### The Applicative Meat

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

```haskell
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](https://en.wikipedia.org/wiki/Infix%5Fnotation?ref=jahans.blog) 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.

![img](https://i.imgur.com/ycfTQvE.png)

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.`

![img](https://i.imgur.com/tXsxaJ1.png)

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.