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
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)
• 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
Functoron type constructors with multiple arguments only apply the
fmap f ...to the last argument (or at least I thought so – see the Pair example below).
I think the answer is that
Either2 x1 is
Either2 a b and
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)