Let me define some terms.  If pi and pi' are two class constraints,
then we say that pi and pi' are overlapping if S(pi) = S'(pi') for
some substitutions S and S'.  Thus C Int and C [a] do not overlap,
but C (a,Int) and C (Bool, a) do overlap.

As it says in the Hugs manual, overlapping instances are allowed,
providing that one of the instances in each overlapping pair is
strictly more specific than the other.  The definition: pi is
more specific than pi' if S(pi) = pi' for some substitution S.
Let us write this as  pi <= pi'.  For example:

       C (Bool, Int) <= C (a, Int) <= C (a, b) <= C a.

For pi to be *strictly* more specific than pi', written pi < pi',
we require that pi <= pi', but that pi' </= pi.  For example, all
the inequalities above are strict:

       C (Bool, Int) < C (a, Int) < C (a, b) < C a.

Thus a program containing these four instance decls is acceptable.
The strict inequality gives us a simple rule for choosing which
instance to use in any given situation without ambiguity:  use
whichever is the closest match.  For example, the class constraints
C (Bool,Int), C (Char,Int), C (Bool,Bool), C Bool would be resolved
using the 1st, 2nd, 3rd, and 4th of the constraints above.

For an example of class constraints that satisfy pi <= pi' but where
pi is not strictly more specific that pi', note that:

     C (a,b) <= C (c,d) <= C (a,b).

A pair of overlapping instances in which neither is more specific than
the other leaves an ambiguity: for example, given two instances C (a,Int)
and C (Bool,a), which should we choose to deal with an instance of the
form C (Bool,Int)?  Either alternative could apply, with potentially
different results depending on the definitions in each instance.  One
way to allow overlapping pairs like this *without* ambiguity, would be
to require that the programmer provide a further instance declaration
to cover precisely the overlapping cases.  For the time being, our
implementations take the simpler step of banning such overlaps altogether.

In the first pair of instances in the question that opened this mini-thread,
one instance was strictly more specific than the the other, hence the pair
was allowed.  In the second pair, there was an overlap, as illustrated by
Lars' example, and neither instance was more specific than the other.
Hence the pair of instances is rejected.

All the best,
Mark



Reply via email to