What does a functor actually look like in various programming languages? We already said it’s something you can use to map, so let’s take a look at some language’s mapping functions:

- Clojure has
`map`

,`mapv`

and`fnil`

- Haskell has
`map`

and`fmap`

. (It also has`<$>`

, which is the same as`fmap`

) - C# has
`Select`

- Java’s streams library has
`map`

and`mapToInt`

So, are any of these functor mapping operations? Well, it won’t take a genius to guess that `fmap`

does the right thing. `map`

in Haskell does the same thing, but only works for `List`

s. The definition of `fmap`

for list is `map`

, so it’s pretty much a wash. (*)

## Land of Compromises

The others? Well, kind of, but you tend to need to squint a bit. The problem is that if you map over an identity function, (e.g. `x => x`

in C#) you should get the same type back as you put in. And actually, that’s very rarely true. `map`

in Clojure can be called on a vector and will return a lazy list. `mapv`

can be called on a lazy list and get back a vector. `map`

in Java and `Select`

in C# send an interface type to the same interface type, but rarely return the exact same type as you were expecting.

Moreover, there isn’t a general mapping interface that lots of functor-like things implement and there isn’t any way to make one. This isn’t a problem for list comprehension, but it horribly breaks functors as a general model of computation. (#) You can still use the concepts, but you’ll end up with a lot of code duplication. Indeed, you’ll probably already have this code duplication and be thinking of it as a pattern. As is all to often the case, low level programming patterns reveal deficiencies in your programming language.

There’s good reasons for these mapping functions not behaving exactly like a functor, though: performance. The haskell compiler has everything, not just lists, as lazy and can optimize types away. Clojure, C# and Java can’t and treat them as hard optimization boundaries.

## Haskell ain’t perfect either

We already established in the previous article that there are plenty of functors that have nothing to do with types. Haskell’s Functor type class is therefore only a functor on the category of Haskell types (usually referred to as *Hask*). This seems good enough, but actually it isn’t.

Consider a set of values. You can easily define a mapping function that satisfies the functor rules. Sadly, `Set`

in Haskell *isn’t* a Haskell Functor. This is because `Set`

imposes a condition on its values that they be sortable. Whilst this isn’t a problem for real Functor’s, it’s a problem for Haskell functors because type classes don’t admit restrictions on their type parameters. To put it another way, `Functor`

in Haskell is a functor over the whole of *Hask*, never a subcategory. For that matter, you can’t do the (*2) functor that I described last time in any sensible way because you can’t restrict its action to integers.

It turns out this problem is fixable, with Rank-2 typeclasses, but don’t hold your breath for that to land in Prelude any time soon. In the meantime, you can’t use `Functor`

to represent functors with domain type restrictions.

(*) Many smart Haskellers believe (and I agree with them(+)) `map`

should work on all functors and `fmap`

should be retired. There’s a general theme here: the standard libraries are showing their age and need work to simplify them.

(+) If you’ve never seen Alan Rickman play Obadiah Slope, you’re missing out.

(#) If you’re prepared to lose information, all you really need is reduce/Foldable anyway.