This is a good question because it made me think about why Haskell behaves this way.
class PseudoArbitrary a where arb :: a instance PseudoArbitrary Int where arb = 4 instance PseudoArbitrary Char where arb = 'd' instance PseudoArbitrary Bool where arb = True reallyDumbFunc :: (PseudoArbitrary a, PseudoArbitrary b) => Either ab -> Either ab reallyDumbFunc (Left x) = Right arb reallyDumbFunc (Right x) = Left arb
So check this out. I made a typeclass PseudoArbitrary where typeclass instances provide a (pseudo) arbitrary element of their type. Now I have a reallyDumbFunc that takes Either ab , where both a and b have PseudoArbitrary instances, and if a Left was entered, I create a Right , with a (pseudo) arbitrary value of type b in it and vice versa. So now let's play ghci:
ghci> reallyDumbFunc (Left 'z') Ambiguous type variable blah blah blah ghci> reallyDumbFunc (Left 'z' :: Either Char Char) Right 'd' ghci> reallyDumbFunc (Left 'z' :: Either Char Int) Right 4
Wow! Despite the fact that everything I changed was an input type, it completely changed the type and value of the output! This is why Haskell cannot solve this ambiguity on its own: because it will require a complex analysis of your function to make sure that you are not doing things like reallyDumbFunc .
source share