Functor
A functor is an abstract concept, so we will begin with some examples.
In order to have an example to work with, define the function:
f :: Double -> Double
f x = x*x
If you want to apply f to a single number, no problem.
ghci> x = 10
ghci> f x
100
What if you want to apply f to a bunch of numbers?
ghci> xs = [10,20,30]
You probably know about map.
ghci> map f xs
[100,400,900]
The function fmap does the same thing in this case.
ghci> fmap f xs
[100,400,900]
What would it mean to apply f to a Maybe Double?
With an input of Just 10, it would make the most sense for f to
output Just 100. With an output of Nothing, the sensible output
(from any function) would be Nothing.
That is what fmap is made to do.
ghci> mx = Just 10
ghci> fmap f mx
Just 100
ghci> nx = Nothing
ghci> fmap f nx
Nothing
Haskell allows you create an fmap function for your own data types
by making them instances of the Functor class. The definition of
fmap for Maybe looks like this:
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap f (Nothing) = Nothing
As you can see, it specifies how fmap f acts on all of the
possibilities for input.
Exercises A
-
Give two different typed examples of the
Taggedtype.data Tagged a = Tagged String a -
Is there a sensible way to apply the function
snbelow to aTagged String?sn :: String -> (Int, String) sn w = (100 * length w, w) -
What type(s) could you use for
athat would let youTagged ans :: Int -> [String] ns k = replicate k "Tag"
Can you turn this data definition into a Functor instance?
Exercises B
Use the Data Types page for the definitions used below.
Important note about functors: fmap is only supposed to operate on the last type
-
Write the instance declaration to make
Triplean instance ofFunctor.data Triple a = Never | Unlikely a | Surely a -
Write the instance declaration to make Twin (below) an instance of
Functor.data TwinL a = NotPresent | TwinR a a -
Make
YikesaFunctor.data YikesL a b = YikesR a a b -
A binary tree
data Tree a = Leaf a | Tree {getValue :: a, getLeft :: (Tree a), getRight :: (Tree a)}- Make an example of a tree with only one value.
- Make an example of a tree with three values (one on the left, one on the right).
- Make Tree into a Functor.