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 of Functor:
instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
Now, I’m trying to understand why the implementation maps in the case of a Right value constructor, but doesn’t in the case of a Left?
Here is my understanding:
First let me rewrite the above instance as
instance Functor (Either a) where
fmap g (Right x) = Right (g x)
fmap g (Left x) = Left x
Now:
-
I know that
fmap :: (c -> d) -> f c -> f d -
if we substitute
fwithEither awe getfmap :: (c -> d) -> Either a c -> Either a d -
the type of
Right (g x)isEither a (g x), and the type ofg xisd, so we have that the type ofRight (g x)isEither a d, which is what we expect fromfmap(see 2. above) -
now, if we look at
Left (g x)we can use the same reasoning to say that its type isEither (g x) b, that isEither d b, which is not what we expect fromfmap(see 2. above): thedshould be the second parameter, not the first! So we can’t map overLeft.
Is my reasoning correct?
This is right. There is also another quite important reason for this behavior: You can think of
Either a bas a computation, that may succeed and returnbor fail with an error messagea. (This is also, how the monad instance works). So it’s only natural, that the functor instance won’t touch theLeftvalues, since you want to map over the computation, if it fails, there’s nothing to manipulate.