Overlapping Instances + Existentials = Incoherent Instances

Stefan Holdermans stefan at cs.uu.nl
Wed Feb 3 11:34:27 EST 2010


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


More information about the Glasgow-haskell-users mailing list