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

Reply via email to