Reputation: 11
I'm new with the Functor, so I have parameterised type List like this:
data List a = Empty | One a | Append (List a) (List a)
and the question asked me to change it into an instance of the Functor class in Haskell syntax. I'm struggling in define for each fmap
Upvotes: 0
Views: 106
Reputation: 52290
Here is your structure again (a bit nicer formated):
data List a
= Empty
| One a
| Append (List a) (List a)
You are asked to define a Functor-Instance for that so let's start by pattern-matching on the 3 constructors:
instance Functor List where
fmap f Empty = ...
fmap f (One a) = ...
fmap f (Append a b) = ...
in the Empty
there is (aside from bottom-values like undefined
, ...) really only one possibility - you have to return a List a
- Empty
is possible, for One
you'd need one a
-value (which you don't have) and for Append
you'd need two List
s again. Sure you could take Append Empty Empty
but remember one of the functor-laws states fmap id l === l
for all Lists l (meaning exactly the same - not Haskells Eq
!) - so there is only one choice:
instance Functor List where
fmap _ Empty = Empty
for One
it's similar: you need fmap id (One a) === One a
so the constructor is fixed and for the general case fmap :: (a -> b) -> List a -> List b
you see that you have to use f
on the wrapped a
-value in One
:
instance Functor List where
fmap f (One a) = One (f a)
Finally for the Append
-case. By now you should know that this needs to result in Append (..) (..)
again (functor-law) and the two arguments to Append
on the right-side needs to be List b
. Now how to get List b
when you have List a
? If you look around: fmap f :: List a -> List b
so you have a way to turn List a
s (of which you have two in scope) into List b
s (maybe not surprising as Append
is recursive too) and again the functor-laws only let you one choice (why?):
instance Functor List where
fmap f (Append a a') = Append (fmap f a) (fmap f a')
so you get:
instance Functor List where
fmap _ Empty = Empty
fmap f (One a) = One (f a)
fmap f (Append a b) = Append (fmap f a) (fmap f b)
PS: Normally - not Homework - you could do:
{-# LANGUAGE DeriveFunctor #-}
module ... where
data List a
= Empty
| One a
| Append (List a) (List a)
deriving Functor
and the GHC will figure this out for you ;)
Upvotes: 1