Functor on the Typeclassopedia.

The Functor is the most fundamental typeclass in the standard libraries. Intuitively, a Functor can be viewed as a sort of “container,” coupled with an ability to apply a function to every element in the container. One example is a list: this is a container of elements, and we can uniformly apply a function to every element using map.


Having a single fmap method means that we don’t have to implement and remember several map methods for different data structures e.g. map over lists, treeMap, maybeMap.

This also enables us to write code that works with any Functor, simply by invoking fmap polymorphically. This enables a powerful sort of code reuse.


There are two main intuitions for Functor.

  1. A Functor is a container, or more precisely, a computational context we can map over. Data structures are the most natural example of this.

  2. Since fmap is curried, we can write the type signature as fmap :: (a -> b) -> (f a -> f b). It transforms a “normal” function g :: a -> b into one that operates over containers fmap g :: f a -> f b. This transformation is called a lift.

The [] instance

Recalling the familiar pattern of mapping over a list, we can implement an instance of Functor as follows.

As we’d expect, fmap works like map:

ghci> fmap (\x -> x + 2) [1..10]
ghci> fmap (*2) [1..10]

The Maybe instance

Similarly, Maybe is an instance of functor:

The Tree instance

Suppose we have a Tree data structure defined recursively as follows:

We can write a Functor instance as follows:

This gives us a function that operates as follows:


There are two laws any Functor instance must satisfy:

  1. fmap id = id

This just means mapping id over a container must leave the container unchanged.

  1. fmap (g . f) = fmap g . fmap f

This says that it doesn’t matter whether we map a composed function or first map one and then the other.


Applicative on the Typeclassopedia.

Further references