For an instance, Either a fmap is of the following type:
(i -> j) -> Either ai -> Either aj
In this equation:
fmap _ (Left x) = Left x
it is known that the second argument is of type Either ai and matches the Left x pattern. Take x out and apply Left to it to get the result of fmap .
The trick is that Left on the left side of the equation is not the same as Left on the right side! On LHS Left this constructor:
Left :: a -> Either ai
Whereas on RHS Left is a constructor:
Left :: a -> Either aj
The RHS Left used in the template would not match the fmap type of the second argument Either ai , and LHS Left would not produce the type value needed as the fmap result Either aj .
Thus, it is not possible to use the same Left for both things, semantically; you need to build a new Left x :: Either aj containing x found in Left x :: Either ai . Haskellβs implementation may or may not represent the two terms in the same way and may or may not share the same representation in memory of two values ββwith different types and may or may not be smart enough to optimize the construction of a new value that will be presented identically to another value, which it already has at hand. But these implementation problems are different from what the program means, and the role of type checking makes pure sense.
Ben
source share