The Functor class in Haskell, what is it?

Angelica Urbanelli
ELP-2018
Published in
4 min readJan 30, 2019

For those who have already programmed in Haskell, you’ve surely faced with many type classes such as Ord or Eq which are for things that can be respectively ordered and equated. Or, even if you never used this programming language, you just need to know that, as you might have noticed, this kind of classes are a sort of interface that defines some behaviour. Here we are going to talk about another type class called Functor, showing its properties and its features.

The main characteristic of this class is that it is for things that can be mapped over, and this can probably make you think about lists, and especially to the function map that can be applied on them.

But let’s proceed in order. Here there is the implementation of the Functor class:

implementation of Functor class

As you can see it simply defines the function fmap without giving any implementation of it, we just can learn from its signature that it takes a function from one type a to another type b and a functor applied on a and it returns a functor applied on b.

The interesting thing is in the type of the function itself: here f is not a concrete type (such as Int, Bool, Char…), but a type constructor whose parameter is a type. This might sound a bit confusing but let me try to clarify with the following example.

As I said before, this function is pretty similar to the function map, whose signature is: map :: (a -> b) -> [a] -> [b]

It is really close to the fmap one: it takes a function from one type to another and a list of one type and returns a list of another type. Is it just a coincidence?

Well, obviously, it is not! In fact, lists are functors themselves, and the function map is fmap that works only on lists!

Here’s an example showing that fmap and map have the same behaviour when applied on lists:

an example using fmap and map

But how can we force a type to have this behaviour?

The answer is that the type must be an instance of the Functor type class. To better understand, let’s take a look at how this is made with the type list:

how the type list is an instance of Functor

This syntax might not be so clear for you (don’t worry, this is not the point), but I just would like to show that this instance is made on the type list itself, and not to a list of a particular type. In fact, the type list is, by definition, a parametrized type. This means that it is a type that takes another type to produce other types, such as list of Int, list of String, list of lists of String, and so on.

And this is the real point.

The Functor type class can’t be instantiated by every type, but just by those that takes one type parameter. Like list, there are many other types that have this feature, and that, by consequence, can be an instance of Functor. For example, the Tree type, that I’m going to explain better in the next paragraph.

The Tree type is either an empty tree or a node-root with two node-sons. As said before, this type takes a one type parameter, so it can be used to create, for example, a Tree of Int, or a Tree of Char; and it is also an instance of Functor, as you can see below:

how the type Tree is an instance of Functor

This means that it is possible to use the function fmap to map over a Tree, applying a function on a node and on their left son and right son, and so on recursively, which can be very useful and easy.

In conclusion

The Functor is a type class that can be instantiated by type constructors for making them to be mapped over. It is a really powerful tool in functional programming and it can be seen as a high-level concept of implementing polymorphism.

Bibliography

--

--