Hi all,
looks like this instance thing is a terrible mess, currently.
In principle, if we have
class Sub Base a => a
instance Base C1 => t
for some t and then
instance Sub C2 => t
it should hold for C2 that it must constrain t no less than C1.
Or, to put it differently, that C1 must be implied by C2.
Yet, this is currently checked nowhere in the compiler.
In addition, the order of individual constraints should be immaterial, but this is the lesser problem.
For example, the compiler accepts the following nonsense:
instance Base Ord a => Maybe a where
base = error "base"
instance Sub Show a => Maybe a where
sub = error "sub"
Luckily, the generated code is not valid either, so javac stops this from being compiled.
It looks like I'll have to rethink (and recode) this one from ground up, so do not expect a quick fix.
In the meantime, please observe that C2 must imply C1 and, as a nasty side condition, that the order of constraints in C2 must match the order of corresponding constraints in C1 and new constraints in C2 must be put last.
Thus, in spite this being a severe compiler error, it does not prevent us from writing correct programs that will also have the same meaning once the error is fixed.
In short:
- Some correct programs are compiled correctly.
- Some correct programs are compiled to invalid java code. But by reordering constraints, one can obtain a semantically equivalent program that works.
- Some invalid programs are not diagnosed as such and are compiled to invalid java code.
Thanks to Yorrick for figuring this out, Thanks to Marimuthu for providing the essential workaround.