
On Saturday 18 September 2010 8:27:45 am Gábor Lehel wrote:
Hmm. I had a similar thought, but dismissed it because I was under the impression that you needed to use all the parameters of the class as parameters of its associated types. But apparently that was mistaken -- or, at least, your example compiles. :)
Classes of the form I sent: class (T1 b ~ a, T2 a ~ b) => C a b where type T1 b :: * type T2 a :: * ... actually desugar into the following: type family T1 b :: * type family T2 a :: * class (T1 b ~ a, T2 a ~ b) => C a b where ... So the parameters of the families needn't match the parameters of the class. It does impose some additional constraint on your making instances of the families whenever you make an instance of the class, which wouldn't be there if you wrote them separately, but I think that's it. This is also important when translating classes like the following: class Closed a | -> a where ... You can only write a single instance of that class (although, I'd guess that GHC currently accepts 'instance Closed a where ...', which should be illegal). To translate it to type families, you write: class Closed a where type T :: * ... a family with no parameters. The compiler will only allow you to write one instance for that family, but you must provide an instance for each instance of the Closed class. Hence, you can only write a single instance of the Closed class. -- Dan