| >    delete :: (Dictionary dict key dat) => key -> dict -> dict
| 
| It would not *always* result in ambiguity. For example, consider
| 
|       instance Dictionary (MyDict dat) Int dat where ...
| 
|       f :: MyDict dat -> MyDit dat
|       f d = delete (3::Int) d
| 
| Here, the polymorphism in 'dat' doesn't affect which instance
| is chosen.

Even if you relaxed the restriction on ambiguously typed members in a
class declaration, I don't think this definition of f would be accepted.
The principal type of f ought to be:

 (Dictionary (MyDict dat) Int dat') => MyDict dat -> MyDict dat
                              ^^^^

Note that the third parameter is still `ambiguous' (in the sense that
it doesn't appear in the type to the right of the => arrow).  From a
type inference perspective, dat' enters the scene when you instantiate
the polymorphic type for delete with three new type variables.  The fact
that you have an instance declaration for a tantalizingly similar
class constraint doesn't help, because we can only use it if we can
force dat and dat' to be equal.  And for that, you need a more powerful
mechanism (improvement, for example) for resolving overloading that goes
some way beyond current Haskell.

All the best,
Mark


Reply via email to