Haskell’s standard module ships with two functions, called
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:
map :: (a -> b) -> [a] -> [b] map _  =  map f (x:xs) = f x : map f xs
foldr, we can write an identical function with an even shorter defintion:
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
class Functor (f :: * -> *) where fmap :: (a -> b) -> f a -> f b
As it turns out,
 is an instance of
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
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
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.