Hi Marko,

| I have something similar to 
| 
| > class (Eq a) => Substitutable a where
| >  match :: a -> a -> Maybe (Substitution a)
| >  applySubst :: Substitution a -> a -> a
|
| and two Types Type1, Type2, both of which are instances of class
| Substitutable. ... but defining
| 
| > instance Substitutable a => Substitutable (a,b) where
| >   applySubst sigma (x,y) = (applySubst sigma x, y)
| > instance Substitutable b => Substitutable (a,b) where
| >   applySubst phi (x,y) = (x, applySubst phi y)
| 
| obviously has an overlapping instance (which will never occur).

But the overlapping instance *could* occur, for example, at types of
the form (Type1,Type1), (Type1,Type2), (Type2,Type1), (Type2,Type2).
And in just the first of those cases, there are (at least) three
possible interpretations that you might get:

   applySubst sigma (x,y) = (applySubst sigma x, y)
   applySubst sigma (x,y) = (x, applySubst sigma y)
   applySubst sigma (x,y) = (applySubst sigma x,
                             applySubst sigma y)

My point here is that there are fundamental problems with using
overloading here ... overloading only makes sense if you can tell
from the type exactly which version of the symbol is intended.

However, all is not lost.  Jeff Lewis has been working on an
extension which he calls `multiple instance resolution', and
has implemented a version of this that will be available in
the next Hugs 98 release (given a command line flag).  In short,
it works by delaying the check for overlapping instances, and
using the contexts of two potentially overlapping instances to
distinguish between them.  If only one instance applies, then
things will work as you intended.  However, if multiple instances
apply, then you'll get a type error, as before.

All the best,
Mark



Reply via email to