
Dan,
class C a where foo :: a -> String
instance C a where foo _ = "universal"
instance C Int where foo _ = "Int"
[...]
Now, IncoherentInstances is something most people would suggest you don't use (even people who are cool with OverlappingInstances). However, it turns out that ExistentialQuantification does the same thing, because we can write:
data Ex = forall a. Ex a
baz :: a -> String baz x = case Ex x of Ex x' -> foo x'
and this is accepted, and always yields "universal", just like bar. So, things that you get out of an existential are allowed to make use of the general versions of overlapping instances if any fit.
I don't think it's the same thing. The whole point of the existential is that at the creation site of any value of type Ex the type of the value being packaged is hidden. At the use site, therefore, the only suitable instance is the one for C a. In particular, there is no way for the baz to tell whether an Int is wrapped in the existential. However, if we pack a dictionary along, as in data Ex = forall a. C a => Ex a then, you'll find that baz will pick the dictionary supplied with the existential package rather than the one from the general instance. Cheers, Stefan