Overlapping Instances + Existentials = Incoherent Instances
stefan at cs.uu.nl
Wed Feb 3 11:34:27 EST 2010
> 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
> 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
> 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.
More information about the Glasgow-haskell-users