One of the things that people new to Haskell may not appreciate is that academia’s love affair with monads has been waning for some time. In its place is a more nuanced hierarchy of Functor, Applicative, Monad. (*)

So what the heck is a functor? Well, really it’s just something you can map over and it makes sense. “Makes sense” has a specific mathematical meaning, but I’m going to gloss over it and keep going.

Let’s talk about some things you can map over:

• A list, `[a]`
• A set, `Set a`
• A nullable value, `Maybe a`
• A random value, `Rand StdGen a`
• A function returning a value, `(->) a`
• A program returning a value, `IO a` (We’ll ignore this one from now on, I’m just mentioning it because IO is kind of important.)
• A record, where we only map over one of the fields. e.g. imagine a pair `(x,y)` where x and y are different types

So, if you were mapping “add one” you’d get

• A list where all of the values were one larger e.g. [2,4] becomes [3,5]
• A set where all of the values were one larger e.g. #(2,4) becomes #(3,5).
• A value one larger, or null. So null becomes null, and 3 becomes 4.
• A random integer value between 1 and 6 becomes a random integer value between 2 and 7.
• A function f(x) becomes a function g(x) where g(x) = f(x) + 1
• The pair (x,y) becomes (f(x),y)

I’ve found that while getting your head around the concept, it’s best to just concentrate on nullable values and lists. In particular, if you’re familiar with Clojure or LINQ, it’s about understanding that things like nil-punning and `fnil` are exactly the same concept as map and behave the same way.

Just to complicate matters, the set example doesn’t actually work in Haskell, but I’ll get to that in a later post. 