fmap
has the signature:
fmap :: Functor f => (a -> b) -> f a -> f b
So that means that it will - given a function that maps from a
to b
, produce a function that maps Stuff a
to Stuff b
. But the attributes of Stuff
are not a
s, so you cannot call f
on the arguments directly.
So that probably means you want to make StuffPart a
a Functor
first. For instance:
instance Functor StuffPart where
fmap f (Add x y) = Add (f x) (fmap f y)
fmap _ End = End
It looks like StuffPart
is your custom defintion of a list ([]
).
and then we can simply define:
instance Functor Stuff where
fmap f (Stuff x y) = Stuff (fmap f x) (fmap f y)
Note that the fmap
s we call here (the ones in boldface) refer to the function we defined above (in the context of Functor StuffPart
).
EDIT: you do not have to make StuffPart
a Functor
per se. If you do not really want that, you can simply define a function foo :: (a -> b) -> StuffPart a -> StuffPart b
and call that function, but this actually looks like bad code design to me, since if you later alter the definition of StuffPart
then parts about Stuff
have to change as well, making it harder. But if you really want that, you can use:
instance Functor Stuff where
fmap f (Stuff x y) = Stuff (foo x) (foo y)
where foo (Add x y) = Add (f x) (foo y)
foo End = End
StuffPart
, same as a list... Or just enableDeriveFunctor
to do the job for you... – karakfa