In my free time I\'m learning Haskell, so this is a beginner question.
In my readings I came across an example illustrating how Either a
is made an instance
As others mentioned, Either
type is a functor in its both arguments. But in Haskell we are able to (directly) define only functors in a type's last arguments. In cases like this, we can get around the limitation by using newtype
s:
newtype FlipEither b a = FlipEither { unFlipEither :: Either a b }
So we have constructor FlipEither :: Either a b -> FlipEither b a
that wraps an Either
into our newtype
with swapped type arguments. And we have dectructor unFlipEither :: FlipEither b a -> Either a b
that unwraps it back. Now we can define a functor instance in FlipEither
's last argument, which is actually Either
's first argument:
instance Functor (FlipEither b) where
fmap f (FlipEither (Left x)) = FlipEither (Left (f x))
fmap f (FlipEither (Right x)) = FlipEither (Right x)
Notice that if we forget FlipEither
for a while we get just the definition of Functor
for Either
, just with Left
/Right
swapped. And now, whenever we need a Functor
instance in Either
's first type argument, we can wrap the value into FlipEither
and unwrap it afterward. For example:
fmapE2 :: (a -> b) -> Either a c -> Either b c
fmapE2 f = unFlipEither . fmap f . FlipEither
Update: Have a look at Data.Bifunctor, of which Either
and (,)
are instances of. Each bifunctor has two arguments and is a functor in each of them. This is reflected in Bifunctor
's methods first
and second
.
The definition of Bifunctor
of Either
is very symetric:
instance Bifunctor Either where
bimap f _ (Left a) = Left (f a)
bimap _ g (Right b) = Right (g b)
first f = bimap f id
second f = bimap id f