As you may have noticed I’m a little obsessed with functional programming at the moment. I’ve recently been reading up on bizarre-sounding terms like functors, applicatives and monoids in Learn You A Haskell, only to discover they’re not nearly as incomprehensible as they sound. This post outlines some of the information on functors that this newbie has been able to pick up so far.

**Note:** One thing I’ve noticed while reading introductory FP material is that each concept seems quite small and understandable, but happens to depend on another million or so small and understandable things. I find this makes it difficult to write about without assuming lots of knowledge, going down a rabbit hole of detail, or glossing over potentially important points. For this post I’ve elected to gloss over details like type constructors and type classes in favour of trying to give a general overview. If you’d like to get the details instead, skip through to the References, starting with Learn You A Haskell.

## Types containing values

Many types can be thought of as holding values. For example, lists and arrays can hold integers, strings or other types of values. In .NET, we have the `Nullable<T>`

type, which can hold `null`

, or a value of type `T`

. In Haskell there’s the `Maybe a`

type, which similarly can hold `Nothing`

or an `a`

. We can even think of commands or partially evaluated functions as holding values: once they finish executing they’ll have or return a particular value.

For now, let’s just think of these types as boxes or containers that can hold values of some type.

## Mapping over boxes of values

Say we have a function `fn`

which can take some value of type `a`

and return a value of type `b`

. In Haskell we express this as `fn :: a -> b`

, or as `Func<A,B> fn`

in C#.

Now imagine we have some sort of box that can hold some quantity of `a`

. We’d like to apply `fn`

to the `a`

we have in the box, and get a new box of `b`

. But `fn`

works on an `a`

, not on a “box of `a`

”, so we need a way of apply our `fn`

inside the box, and then a way of shoving the resulting `b`

into a new box.

The solution is to define a function called `fmap`

which does exactly that. It takes a function `(a -> b)`

, and a box of `a`

, and returns a box of `b`

:

```
-- Pseudo-Haskell
fmap :: (a -> b) -> boxOf a -> boxOf b
// Pseudo-C#
Box<B> Fmap<A,B>(Func<A,B> fn, Box<A> boxOfA);
```

## Defining fmap

Now we’ve previously mentioned that these boxes can actually be different types (lists, `Maybe`

s or `Nullable<T>`

s). How does `fmap`

know how to unpack and repack all the different types of boxes?

To be able to do this, each type of box needs its own implementation of `fmap`

. Boxes that have a valid `fmap`

defined for them are called *functors*. Haskell has a lot of these built-in, but we could also define them ourselves:

Notice that `fmap`

for a list is exactly the same as normal `map`

. In other words, we iterate over each value in the list, apply the function to each, and then return the new list. For `Maybe`

, mapping the function over `Nothing`

returns `Nothing`

. Mapping over an instance that holds a value gets that value, applies the function to it, and returns a new instance of `Just`

the result.

C#’s type system doesn’t support all the features we need to get a lot of use out of functors, but we can still get an idea of how `fmap`

might look for enumerables and nullables:

## Graduating from boxes

Notice that `fmap`

preserves the type of box used. For example, if we call `fmap`

on a list, we’ll get another list back. If we call `fmap`

on a `Maybe`

, we’ll get another `Maybe`

back. We never call it with a list and get a `Maybe`

back. If we call our box `f`

, then calling `fmap`

on `f a`

will give us back an `f b`

. The `f`

is preserved.

Rather than using the box analogy, the type `f`

is often referred to as the *context*, so `f a`

is an `a`

value in the context of `f`

. An `a`

in a context where there maybe be 0 or more values is a list of `a`

. `Maybe`

is a context that may have zero or one `a`

. `fmap`

maps a function from `a`

to `b`

, preserving the context.

## Lifting functions is useful

Haskell (and I assume most functional programming languages) has some really interesting ways of putting types together. It is quite common to have simple data types (like integers, strings etc) and functions that operate on them. We can also have more complex data types that can work over many types (they are *polymorphic*), such as lists of `a`

or `Maybe a`

(where `a`

can be an integer, string, function or even another type of list). Because this polymorphism is so common, it would be nice to be able to reuse functions that work on simple types in different contexts, and that’s exactly what functors let us do.

This is known as *lifting* a function; transforming a function like `a -> b`

to work in another context, like `f a -> f b`

.

For example, we can use lift a standard integer operation like (+1) to work on `Maybe Int`

:

```
ghci> fmap (+1) (Just 10)
Just 11
ghci> fmap (+1) Nothing
Nothing
```

Or apply a standard string function to a `Maybe String`

:

```
ghci> fmap reverse (Just "hello world!")
Just "!dlrow olleh"
ghci> fmap reverse Nothing
Nothing
```

And then of course there is the familiar mapping over a list (as mentioned earlier, `map`

, or `Select`

in .NET, is just `fmap`

for list):

```
ghci> fmap (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
csharp> new[] {1,2,3,4,5,6,7,8,9,10}.Select(x => x*2);
{ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }
```

As a pure functional language, Haskell eschews code with side-effects, which includes some innocuous-sounding things like reading or writing to files. To work within this restriction, side-effects can be wrapped up in types like `IO a`

. Because `IO`

is a functor, we can use `fmap`

to work with the value inside the `IO`

context without having to explicitly pull out the value (so side-effects stay neatly wrapped up in their `IO`

box). Say we wanted to read an integer from STDIN, here’s how it would work with and without `fmap`

:

Finally, functors are just one part of a large hierarchy of type classes. Other type classes like applicative functors and monads build on the properties of functors to provide their own interesting capabilities.

## Well-behaved functors

We’ve seen that functors are types that can can have functions mapped over them, thanks to an corresponding implementation of `fmap`

. That’s the bulk of it, but there are also two formal properties that these `fmap`

implementations need to have in order for a type to act as a functor.

The first is that mapping the identity function over a functor is the same as calling the identity function directly on the functor. `id`

is the identity function in Haskell, the C# equivalent being `x => x`

. The identity function takes an argument and returns it, unchanged.

```
fmap id a = id a
-- Example
ghci> id (Just 42)
Just 42
ghci> fmap id (Just 42)
Just 42
```

The second is that composing two functions then mapping them needs to give the same result as mapping each function in turn. In other words:

`fmap (f . g) = fmap f . fmap g`

Typeclassopedia’s entry on functor laws mentions that satisfying the first law automatically satisfies the second. Which is good, because to me the first is a lot easier to follow. :)

These properties aren’t enforced by the type system, but we need to make sure our functors have them or else our functor won’t behave like all the other nice functors. These properties guarantee that `fmap`

preserves the structure (or context) of our functor.

## References

- “Functors, Applicative Functors and Monoids”, Learn You A Haskell
- “Functor”, Wikipedia
- “Map (higher-order function)”, Wikipedia
- “Typeclassopedia”, HaskellWiki
- “Applicative functors”, Haskell Wikibook