`map`

and `fmap`

in HaskellHaskell’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:

```
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:

```
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`

:

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

As it turns out, `[]`

is an instance of `Functor`

:

```
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`

:

```
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.