I have no idea why fmap _ a = a
below is illegal. Here is the code:
data Sum a b = First a | Second b
instance Functor (Sum a) where
fmap f (Second b) = Second (f b)
fmap _ (First a) = First a
fmap _ a = a -- Why can't I do this instead?
Other question is, does this have performance penalty implications or is something that happens only at compile time?
Regarding performance: quite late in the compilation process, when GHC has erased most type information, it does its best to notice when a value is being reconstructed like that. This step catches a lot of situations, but not all; sometimes the code will have been transformed in such a manner that the reconstruction is no longer obvious.
You need to call the constructor anew to create a new value, so it will have a different type than the one you've started with.
fmap :: (b -> c) -> Sum a b -> Sum a c
fmap (f :: b -> c) :: Sum a b -> Sum a c
fmap (f :: b -> c) (x :: Sum a b) -> Sum a c
a :: a a :: a
First a :: Sum a b First a :: Sum a c
b :: b c :: c
Second b :: Sum a b Second c :: Sum a c
Given a :: a
, First a
has type Sum a t
with t
determined by the context in which First a
appears. The two First a
on both sides of the equal sign define two different values, each of its own type. Using the variable a
on the right, it still refers to the same value of type Sum a b
as it is on the left. But we need a different type, according to fmap
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With