Tom Pledger wrote:
> Marcin 'Qrczak' Kowalczyk writes:
> > [...] However in the following case there is an ambiguity that I
> > don't know how to resolve - overlapping instances don't solve what
> > they seemed to claim to solve:
> >
> > class A a where ...
> > class A a => B a where ...
> > class C a where ...
> >
> > instance A a => C a where ...
> > instance B a => C a where ...
> >
> > How to specify which C instance to apply?
> > ghc -fallow-{overlapping,undecidable}-instances complains
> > about the ambiguity.
>
> If Haskell allowed negation inside predicates, you could write:
>
> instance (A a, not B a) => C a where ...
The problem with GHC in this case is that it only looks at the head of the
instance decl (`C a') to resolve overlaps. Hence, it sees
> instance ... => C a where ...
> instance ... => C a where ...
and gives up because it can't distinguish the two instances.
Hugs is the same way, except if you `:set +m', then you get a little
experimental feature I wrote called `multi-instance resolution'. With this
turned on, hugs defers the ambiguity check until instance lookup time. At
instance lookup time, hugs searches for *all* instances that satisfy, and only
then complains if it finds more than one.
So, what does this mean for the above case. Let's try a concrete example:
> class A a where { a :: a }
> class A a => B a where { b :: a }
> class C a where { c :: a }
> instance A a => C a where { c = a }
> instance B a => C a where { c = b }
> instance A Int where { a = 13 }
> instance A String where { a = "Hello, there." }
> instance B String where { b = "Greetings..." }
Main> c :: Int
13
Main> c :: String
ERROR: Multiple satisfiable instances for C [Char]
in_ C a
in C a
So, when there's an A, but no B, there's no ambiguity, but if there's a B,
both C instances apply, and we get ambiguity. Hmm... looks like the error
message could be a little more helpful ;-)
Going back to Tom's comment, his idea of specifying instance negation implies
something like multi-instance resolution. But once you have multi-instance
resolution, the explicit negation isn't necessary (although might be useful as
commentary to the reader).
--Jeff