Identity
Next let's look at the Identity
functor.
newtype Identity a = Identity { runIdentity :: a }
fmap
should apply the given function to every element in the container, but
Identity
stores exactly one element. Thus,
instance Functor Identity where
fmap f (Identity x) = Identity (f x)
Exercise
Verify the functor laws for the Identity
functor.
Solution
Identity:
fmap id (Identity x) = Identity (id x) -- Definition of fmap
= Identity x -- Definition of id
= id (Identity x) -- Definition of id
Composition:
fmap (f . g) (Identity x)
= Identity ((f . g) x) -- Definition of fmap
= Identity (f (g x)) -- Definition of function composition
= fmap f (Identity (g x)) -- Definition of fmap
= fmap f (fmap g (Identity x)) -- Definition of fmap
= (fmap f . fmap g) (Identity x) -- Definition of function composition
The Identity
functor seems utterly useless. Clearly, a container of type
Identity a
simply stores a value of type a
, that is, it stores the same
information as if it were simply of type a
. That's exactly why it's called
Identity
. Remember that a functor f
maps a type a
to a new type f a
. In
a sense, Identity
is the identity functor that maps a type a
to itself.
Strictly speaking, a
and Identity a
are different types, but logically, we
can view them as being the same because they store the same information.
It turns out that, just as Maybe
, lists, and a few other functors, Identity
is not just a functor but a monad, a functor with additional useful properties.
We will encounter the Identity
functor at the end of the chapter on monads, as
the foundation on which to build other monads.