Skip to content

Notes for Week 12 Applicative Functors Part 1 Functors and Functor Laws

newmana edited this page Mar 1, 2012 · 18 revisions

Links:

Exercises:

Exercise 1

* What are Functors useful for?
* What's the difference between fmap and (.) ?  Explain.

Exercise 2

Demonstrate using an IO action as a Functor.

Exercise 3

Make the following Tree type an instance of Functor:

     data Tree a = Node (Tree a) (Tree a) | Leaf a deriving (Show, Eq)

Use the following test to get it working (returns true):

     testFmap = (fmap (+1000) $ Node (Leaf 100) (Leaf 200)) == (Node (Leaf 1100) (Leaf 1200))

Prove that it follows the two Functor laws by writing the following tests:

     --testIdLaw = 
     --testComposeLaw = 

Links

Questions raised during the group:

You can derive a Functor if you start ghci with "-XDeriveFunctor". So from:

data Tree a = Leaf | Node (Tree a) a (Tree a) deriving (Functor)

It generates:

instance Functor Tree where
    fmap f (Leaf      ) = Leaf
    fmap f (Node l a r) = Node (fmap f l) (f a) (fmap f r)

Answers to Exercises:

Exercise 1

  • Functors are a generalised abstraction for mapping over a type.
  • The function composition using a point-free style (or compose operator) defines operations using the higher order functions themselves. fmap defines it in terms of a function acting on an argument. They are equivalent where:
instance Functor ((->) r) where  
fmap = (.)

Exercise 2

main = do 
  line <- fmap reverse getLine
  putStrLn $ "You said " ++ line ++ " backwards!"

Exercise 3

t = (Node (Leaf 100) (Leaf 200))
t1000 = (Node (Leaf 1100) (Leaf 1200))
testFmap = fmap (+1000) t == t1000
testIdLaw = fmap (id) t == (id t)
testComposeLaw = fmap ((+5) . (*2)) t == (fmap (+5) (fmap (*2) t))

Interesting Asides

  • Jefferson Starship had a number of hits in the late 70s and 80s including: Miracles, We Built This City, Sara and Nothings Gonna Stop Us Now (Mannequin Soundtrack). Great music to roller skate to.
Clone this wiki locally