Category Theory for Programmers Chapter 7: Functors
This helps me because the book was not super rigorous about the definition of a functor which is the following definition: Let $\mathscr{A}$ and $\mathscr{B}$ be categories, a functor $F:\mathscr{A} \to \mathscr{B}$ consists of:
- a function $\mathrm{ob}(\mathscr{A}) \to \mathrm{ob}(\mathscr{B})$ written as $A \mapsto F(A)$;
- for each $A, A’ \in \mathscr{A}$, a function $\mathscr{A}(A,A’) \to \mathscr{B}(F(A), F(A’))$, written as $f \mapsto F(f)$,
satisfying the following axioms:
- $F(f’ \circ f) = F(f’) \circ F(f)$ whenever $A \to^{f} A’ \to^{f’} A’’$ in $\mathscr{A}$;
- $F(1_A) = 1_{F(A)}$ whenever $A \in \mathscr{A}$.
Another thing that ended up being really helpful was considering what are our categories? When thinking about haskell, we start with the category of haskell types, Hask. The morphisms then are just haskell functions as they’re all from some type to another type.
So when thinking about functors in hasekll, our objects are elements of Hask and our morphisms are just haskell functions.
The exercises.
-
Can we turn the
Maybetype constructor into a functor by definingfmap _ _ = Nothing?To verify this, all we need to do is verify the functor laws (axioms) hold. First start with identity.
The
Maybetype constructor takes types from Hask, egx, and turns them into new types,Maybe xwhich is just a subset of Hask. The identity function on these new types uses the same identity function from Hask which is why we can sayfmap id = idin haskell. So for us to verify our “functor”, we need to verify this equality.1. fmap id (Just x) = Nothing (by definition of fmap) 2. fmap id (Just x) = id Nothing (by definition of id) 3. fmap id (Just x) = id (Just x) (by definition of fmap id) 4. id (Just x) = id Nothing (by 2 and 3) 5. (Just x) /= NothingSo we do not get that this definition of
fmapgives us a functor. -
Prove the functor laws for the
readerfunctor. From the book, turning the type constructor(->) rinto a functor by definingfmap :: (a -> b) -> (r -> a) -> (r -> b)which was given asfmap = (.)(see thatr -> a -> bin the first two arguments).First step is showing composition holds. So, given two functions:
f :: a -> bandg :: b -> candg . f :: a -> cwe have the following given someh :: x -> a:1. fmap (g . f) h = (.) (g . f) h (by definition of fmap) 2. fmap (g . f) h = (g . f) . h = g . (f . h) (by associativity of composition) 3. fmap (g . f) h = (g . f) . h = g . (fmap f h) (by def'n of fmap) 4. fmap (g . f) h = (g . f) . h = fmap g (fmap f h) (by def'n of fmap)Next step is to show identity is perserved. It is useful to know (or remember or learn) that
id . x = xandx . id = x.fmap id h = (.) id h = id . h = h = id hSo we’re good. $\blacksquare$
-
Implementing the reader functor is equivalent to implementing a compose function as
fmap = (.). For that, we’ve already done in chapter 1! -
Prove the functor laws for the list functor which was defined in the chapeter as
data List a = Nil | Cons a (List a) instance Functor List where fmap _ Nil = Nil fmap f (Cons x t) = Cons (f x) (fmap f t)First step is showing composition. Starting with our base case,
Nil, we have1. fmap (f . g) Nil = Nil = fmap g Nil = fmap f (fmap g Nil)Because we’ve shown the base case
Nil, all that remains is to demonstrate this holds forCons x tassuming it holds fort(induction).fmap (f . g) (Cons x t) = Cons ((f . g) x) (fmap (f . g) t) = Cons ((f . g) x) (fmap f (fmap g t)) (hypothesis) = Cons (f (g x)) (fmap f (fmap g t)) (def'n of composition) = fmap f (Cons (g x) (fmap g t)) = fmap f (fmap g (Cons x t))$\blacksquare$