# Fantas, Eel, and Specification 6: Functor

27 Mar 2017Fantasy Landers, **assemble**! We’ve been `concat`

enating for two weeks now; are you ready for something a bit different? Well, **good news**! If you’re humming, “*Oh won’t you take me… to functor town?*”, then this is the article for you. Today, friends, we’re going to talk about **functors**.

Another #functional blog post on #functors in #javascript, including Maybe, Either, and... Function :O https://t.co/3H5T0yb35w

— Tom Harding (@am_i_tom) 31 December 2016

Yes, so, at the very end of last year, I wrote an article about functors that went over several examples of `Functor`

types. It’s a collection of examples of how these can be useful *in practice*, but it’s a bit light on **intuition**. Let’s right that wrong today!

I’d recommend giving the above a quick read, as this post won’t spend much time going over what was said back then. tl;dr, `Functor`

is just another **typeclass** (a structure just like `Semigroup`

or `Monoid`

) with one special method:

```
-- Any functor must have a `map` method:
map :: Functor f => f a ~> (a -> b) -> f b
```

… and (*surprise!*) a couple of **laws**. For *any* functor value `u`

, the following must be true:

```
// Identity
u.map(x => x) === u
// Composition:
u.map(f).map(g) === u.map(x => g(f(x)))
```

They might not be *immediately* clear, and the definitions in the other article are a bit wordy, but have a couple reads. In *my* head, I tend to think to myself, *a call to map must return an identical outer structure, with the inner value(s) transformed.*

If this looks a bit *weird* to you, then it’s probably because `Functor`

is the **first** entry we’ve seen in Fantasy Land that *must* **contain** some other type.

Think about `String`

. It has actually ticked all the boxes up until now - it’s a `Setoid`

, `Semigroup`

, *and* a `Monoid`

- but we can’t make it a `Functor`

. This is because `String`

is just, well, strings!

`Array a`

has also ticked all the boxes so far, but it *is* a `Functor`

. This is because it *contains* a value of type `a`

(or, usually, several of them). Strings are just strings - you can’t have a “`String`

*of* a thing” in the same way as you can have an “`Array`

*of* a thing” or a “`Maybe`

*of* a thing”.

** Functor types are containers. Not all container types are functors.** Want an example? Let’s look at

`Set a`

- a collection of *unique*values of some type

`a`

. There’s a catch here, though - `a`

must be a `Setoid`

. Looking at the type signature for `map`

, we see no `Setoid`

restrictions - we could `map`

our `Set a`

values to some not-a-`Setoid`

type `b`

(like `Function`

), and we’d have no way of ensuring uniqueness!A functor **does not care** about the type it’s holding. `Set`

, on the other hand, *must*. Thus, `Set`

can’t be a `Functor`

. Don’t worry, though - there are plenty of types that *are* functors!

Ok, everything has hopefully just about made sense up to here. Now’s when we get a bit… **hand-wavey**. Sorry in advance. We’ve been over the *laws*, and we’ve seen some examples. What’s the **intuition**, though? If all these wildly different types of things are functors, what behaviour do they all *share*?

Imagine a world *without* functors. All we have are basic values: `Int`

, `String`

, `Number`

, that sort of thing. No `Array`

, though. No `Set`

, either, as you’d *internally* need an array of values. No nullable values *at all* (they’re not type-safe). No `Function`

, even! We’d have an **extremely limited** set of tools and would probably throw our computers out the window before too long. But, when we start introducing `Functor`

types:

Type | Capability |
---|---|

`a` |
Represent a value. |

`Maybe a` |
Represent a possibly null value. |

`Either e a` |
Represent a value or exception. |

`Array a` |
Represent a number of values. |

`x -> a` |
Represent a mapping to values. |

… | … |

A functor is like a little “world” in which our boring, functor-less language has been *extended* in some (hopefully useful!) way. When we put a value into one of these worlds, we say that we’re **lifting** the value *into* the functor.

**More than one extension**? What if we want to represent *a number of mappings to values*? We make an `Array`

of `Function`

s! What about a *mapping to a possibly null value*? We write a `Function`

that maps to `Maybe`

s! If we want to combine these capabilities, we simply **nest** them.

We’ll see that we’re not always so lucky with composition-by-nesting when we get on to more complex structures!

We’re there. **That’s what a functor does**. It provides some **extended behaviour**, with total, gorgeous **type safety**. Note that our language isn’t *changed* inside a functor type - just *extended*. This is why the **functor laws** hold. Let’s write a couple of little proofs:

```
// For ANY functor *constructor* U:
// e.g. [x].map(f) === [f(x)]
U(x).map(f) === U(f(x))
// Read: `map` just applies the function to
// the inner value. Using only this rule,
// we win!
const id = x => x
// Identity...
U(x).map(id)
=== U(id(x))
=== U(x) // id(x) === x
// Composition...
U(x).map(g).map(f)
=== U(g(x)).map(f)
=== U(f(g(x)))
=== U(x).map(x => f(g(x)))
```

Our laws hold, everything works. If it helps your intuition, just think of `U(x).map(f) === U(f(x))`

every time you run into a functor. More generally (and correctly), ** map applies a function to the value(s) within a functor** and

*nothing else*. That, friends, is all there is to it!

So, I’m sorry that it got a bit less *clearly*-defined towards the end. You can see it’s quite difficult to define an all-encompassing intuition for functors, but I hope this has given you somewhere to start!

If you want more examples, the Haskell docs contain loads of Functor types for you to see! The intuition will come with time. Until then, as always, feel free to tweet me and I’ll do my best to clarify my ramblings.

Next time, we’ll look at another type of functor: the **contravariant functor**. Get excited! As always, until then,

Take care ♥