I run into this situation often enough for it to be annoying.
Let's say I have a sum type which can hold an instance of x
or a bunch of other things unrelated to x

data Foo x = X x  Y Int  Z String  ...(other constructors not involving x)
To declare a Functor instance I have to do this 
instance Functor Foo where
fmap f (X x) = X (f x)
fmap _ (Y y) = Y y
fmap _ (Z z) = Z z
... And so on
Whereas what I would like to do is this 
instance Functor Foo where
fmap f (X x) = X (f x)
fmap _ a = a
i.e. I only care about the X
constructor, all other constructors are simply "passed through". But of course this wouldn't compile because a
on the left hand side is a different type from the a
on the right hand side of the equation.
Is there a way I can avoid writing this boilerplate for the other constructors?
Best How To :
I assume that we'd like to have a solution for the general case where the changing type parameter is not necessarily in the right position for DeriveFunctor
.
We can distinguish two cases.
In the simple case out data type is not recursive. Here, prisms are a fitting solution:
{# LANGUAGE TemplateHaskell #}
import Control.Lens
data Foo x y = X x  Y y  Z String
makePrisms ''Foo
mapOverX :: (x > x') > Foo x y > Foo x' y
mapOverX = over _X
If our data is recursive, then things get more complicated. Now makePrisms
doesn't create typechanging prisms. We can get rid of the recursion in the definition by factoring it out to an explicit fixpoint. This way our prisms remain typechanging:
import Control.Lens
newtype Fix f = Fix {out :: f (Fix f)}
 k marks the recursive positions
 so the original type would be "data Foo x y = ...  Two (Foo x y) (Foo x y)"
data FooF x y k = X x  Y y  Z String  Two k k deriving (Functor)
type Foo x y = Fix (FooF x y)
makePrisms ''FooF
mapOverX :: (x > x') > Foo x y > Foo x' y
mapOverX f =
Fix .  rewrap
over _X f .  map f over X if possible
fmap (mapOverX f) .  map over recursively
out  unwrap
Or we can factor out the bottomup transformation:
cata :: (Functor f) => (f a > a) > Fix f > a
cata f = go where go = f . fmap go . out
mapOverX :: (x > x') > Foo x y > Foo x' y
mapOverX f = cata (Fix . over _X f)
There's a sizeable literature on using fixpoints of functors for generic programming, and also a number of libraries, for example this or this. You might want to search for "recursion schemes" for further references.