# Lecture 5 — 2018-01-30

## Functor

We talked about the `Functor` type class, defined as:

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

-- LAW: fmap id = id``````

When you see `Functor`, think “Mappable”: a type with a `Functor` instance is one that can be mapped over, i.e., you can change all of the values in the holes while preserving the structure.

Our first example was lists, which was easy: we already know the `map` function well!

``````instance Functor ([]) where
fmap = map``````

We defined a separate type, `Box`, to see how far we could go:

``````data Box a = B a deriving Show

instance Functor Box where
fmap f (B v) = B (f v)``````

We saw how to do it for `Maybe`, too:

``````instance Functor Maybe where
fmap f Nothing = Nothing
fmap f (Just v) = Just (f v)``````

We carefully preserve the structure of our argument: if we’re given a `Nothing`, the types themselves force us to return a `Nothing`. If we’re given `Just v`, we could return `Nothing`, but then we’d violate the `Functor` law that mapping with the identity is the identity.

We also defined ‘readers’, that is, functions whose domain is some fixed type `r`. Readers disrupt our notion of interpreting functorial type constructors of kind `* -> *` as mere ‘containers’, that is, things that might hold some value. Readers are functions—there’s no way to rip open and get the value out of a function. We’ll have to broaden our intuition—that functors are ‘computational contexts’ that will produce a value—perhaps by containing one, perhaps by other means.

In any case, to figure out the instance for `(->) r`, we let types be our guide.

``````instance Functor ((->) r) where
-- fmap :: (a -> b) -> ((->) r a) -> ((->) r b)
-- i.e.    (a -> b) -> (r -> a)   -> (r -> b)
fmap fab fra = \r -> fab (fra r)``````

We didn’t define an instance for an `Either` type, but here’s the one Haskell gives you: the first parameter is fixed, just like readers. Note that `Either :: * -> * -> *` but for a type `e`, we have `Either e :: * -> *`—which is exactly the kind of thing that can be a `Functor`.

``````instance Functor (Either e) where
fmap f (Left err) = Left err
fmap f (Right v) = Right (f v)``````

You’ll notice I used the suggestive name `err` for the left-hand side. Haskell uses the `Either` type to talk about computations that could fail: if an error occurs, we return a `Left`; if we succeed, we return a `Right`. Don’t worry: this choice has more to do the synonymy of “right” and “correct” than politics.