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 as, 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 fmaps 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 enableDeriveFunctorto do the job for you... - karakfa