
Hmm.. okay, here is a rough draft that covers all the important cases I think.
assume the following declarations:
class C1 a where f1 :: t1 f1 = d1
class C2 a where f2 :: t2 f2 = d2 f3 :: t3 f3 = d3
class alias S a => A a = (C1 a, C2 a) where f1 = nd1
okay, the desugaring is as follows:
there are two different desugaring rules, one for instances, one for the alias appearing anywhere other than an instance declaration:
g :: A a => a -> b g = ...
translates to
g :: (S a, C1 a, C2 a) => a -> b g = ...
the triplet of (S a, C1 a, C2 a) is completely equivalent to (A a) in all ways and all places (other than instance heads), one is just a different way to express the other, just like type synonyms. An alias just expands to the union of the classes it is an alias for as well as its class constraints (superclasses).
now for instance declarations
instance A a where f2 = bf2
expands to
instance (S a) => C1 a where f1 = nd1
instance (S a) => C2 a where f2 = bf2 f3 = d3
Note that when declaring an instance of a concrete type, like Int, the constraint (S Int) will be trivially satisfied or not at compile time. (bf2 is free to use methods of 'S' of course).
this translation is also a bijection, declaring those two instances manually as above is indistinguishable from declaring instances via the alias in all ways.
Hopefully the generalization to arbitrary numbers of classes is clear...
What about multiple parameters? Can A have more parameters than the Ci? Should they be in the same order? Should they overlap? What about instance contexts, like: instance I a => A a where ... (What about functional dependencies?) Tom -- Tom Schrijvers Department of Computer Science K.U. Leuven Celestijnenlaan 200A B-3001 Heverlee Belgium tel: +32 16 327544 e-mail: tom.schrijvers@cs.kuleuven.be url: http://www.cs.kuleuven.be/~toms/