# map and fmap in Haskell

Haskell’s standard module ships with two functions, called map and fmap. The first one, map, is the typical function we are all used to in functional programming. Looking at its definition, reveals that it’s recursive implementation is exactly what one would expect:

 1 2 3 map :: (a -> b) -> [a] -> [b] map _ [] = [] map f (x:xs) = f x : map f xs 

Based on foldr, we can write an identical function with an even shorter defintion:

 1 2 map' :: (a -> b) -> [a] -> [b] map' f = foldr ( (:) . f ) [] 

It’s important to avoid tail recursion, because that would make lazy evaluation impossible, which is a prerequisite for dealing with infinite lists. That’s why foldl is a bad idea, even though it would be faster (assuming the compiler performs tail call optimization).

In addition to map, there’s the Functor class, whose instances are required to implement fmap:

 1 2 class Functor (f :: * -> *) where fmap :: (a -> b) -> f a -> f b 

As it turns out, [] is an instance of Functor:

 1 2 instance Functor [] where fmap = map 

So, at least for lists, there’s no difference between the two. However, there are many more Functor instances. For example, let’s examine the instance for Maybe:

 1 2 3 instance Functor Maybe where fmap _ Nothing = Nothing fmap f (Just a) = Just (f a) 

If the value we are mapping over is Nothing, it returns Nothing. Otherwise, it’s applying the given function f to the value from the Just and returns another Just with f’s return value.

Personally, this reminds me of ActiveSupport’s Object#try method. The Functor instance for Maybe is encapsulating exactly the same pattern, but in a more abstract way. That’s because the implementation can be completely different for other types.

The bottom line is that fmap is a generalized version of map. You can fmap whatever you want, as long as there’s a Functor instance for its type. This is extremely powerful, because it allows us to push complexity from the caller to the callee.

From now on, I’m going to use fmap exclusively in my own code: Code that’s using more generalized functions is easier to reuse and change later on.