This is from a “write you own Either with Functor instance” exercise. Writing it is pretty painless:
data Either1 a b = Left1 a | Right1 b
instance Functor (Either1 x) where
fmap _ (Left1 x) = Left1 x
fmap f (Right1 x) = Right1 (f x)
Out of curiosity I switched a
and b
in the data constructors and got an error. I know it is wrong but am looking for a deeper unerstanding.
data Either2 a b = Left2 b | Right2 a
instance Functor (Either2 x1) where
fmap _ (Left2 x2) = Left2 x2
fmap f (Right2 z) = Right2 (f z)
Error
• Couldn't match type ‘b’ with ‘x1’
Expected: Either2 x1 b
Actual: Either2 b b
‘b’ is a rigid type variable bound by
the type signature for:
fmap :: forall a b. (a -> b) -> Either2 x1 a -> Either2 x1 b
Seems I’m missing something
- I know that
Functor
on type constructors with multiple arguments only apply thef
infmap f ...
to the last argument (or at least I thought so – see the Pair example below).
I think the answer is that x1
in Either2 x1
is a
in Either2 a b
and a
in Right2 a
. And since it is already made part of the structure in Functor Either x1
it can’t be modified. But
- I’m not sure I’m right
- and, re “already made part of the structure” I suspect there is a better/standard way of saying that
- I don’t get what the error message is trying to say
This example broke what I though was a rule (“only modify the last argument to the type constructor”). I found many examples of this written exactly as below, so I’m led to think it is correct?
data Pair a = Pair a a
instance Functor Pair where
fmap :: (a -> b) -> Pair a -> Pair b
fmap f (Pair a b) = Pair (f a) (f b)