The following code doesn't compile:
foo :: Num a => (a -> a) -> Either Integer Double -> Either Integer Double
foo f x = case x of
Left i -> Left $ f i
Right d -> Right $ f
and give the following error:
Couldn't match type `Integer' with `Double'
Expected type: Either Integer Double
Actual type: Either Integer a
In the expression: Right $ f d
In a case alternative: Right d -> Right $ f d
This is a follow up question to this question, the problem is solved by using RankNTypes:
(forall a. Num a => a -> a)
But the answer didn't say anything. I want to know:
what's the root cause of this error? The eventual result would only be one of the case branch, f wouldn't be typed to two types at the same time, the type of
fshould be checked as long asf :: Num a => (a -> a), either Integer -> Integer or Double -> Double should work, could someone elaborate why this causes an error?Is there any other way to fix the error? Why RankNTypes would fix the error? This strike me like the Monomorphism Restriction error I got the other day, but the enable it doesn't help me fix this, and the explicit type annotation doesn't work either.
foo (+ 1.5) (Left 5)? If not, why not? If yes, what would the result be?foo f = either (Left . f) (Right . f).