Writing something like this works fine:
data Either a b = Left a | Right b
instance Functor (Either a) where
fmap _ (Left x) = Left x
fmap f (Right x) = Right (f x)
Now lets say I want to invert this, Left applies f to value:
instance Functor (Either a) where
fmap _ (Right x) = Right x
fmap f (Left x) = Left (f x)
This doesn't compile, I suppose I need to have something like Functor (Either _ b), how do I do this?
You can't, and you shouldn't. If you could do this, it would make it a lot tougher to know whether
fmap (+1) (Left 1)should beLeft 1orLeft 2.BifunctorThat said, the abstraction you are looking for (something which can be mapped over on either side) exists and is called a
Bifunctor. Then, depending on whether you want to map over theLefts or theRights, you usefirstorsecond:FlipAlternately, if you want to stick to
fmaponly and not be bothered withfirstandsecond, you can wrap your data type in theFlipnewtype, which has the effect of looking for the functor instance of the second type variable. You still rely on the fact thatEitheris aBifunctor, but you avoidfirstandsecond: