purescript/purescript — pull request #355 by paf31 (2014-04-06 02:09:03+00:00)
Title: Superclasses

I've been working on this on the `superclasses` branch. I have a slightly different approach which gives quite a nice answer to the question of how to ensure superclass instances exist:

Given the following

```
class Su a where
su :: a -> a

class (Su a) <= Cl a where
cl :: a -> a -> a

instance suNumber :: Su Number where
su n = n + 1

instance clNumber :: Cl Number where
cl n m = n + m

test :: forall a. (Cl a) => a -> a
test a = su (cl a a)
```

The following JS is generated:

```
var suNumber = function (_) {
return {
"__superclasses": [ ],
su: function (n) {
return n + 1;
}
};
};
var clNumber = function (_) {
return {
"__superclasses": [ function(_) { return suNumber({}); } ],
cl: function (n) {
return function (m) {
return n + m;
};
}
};
};
var test = function (__dict_Cl_10) {
return function (a) {
return su(__dict_Cl_10["__superclasses"][0]())(cl(__dict_Cl_10)(a)(a));
};
};
```

TLDR: we add a `__superclasses` field to every dictionary (we can remove this field if there are no superclasses), and add another search path in `entails` which looks for instances via superclasses. You can see the result in `test`.

The implementation of `__superclasses` in `Sugar/TypeClasses.hs` just uses the existing `TypeClassDictionary` placeholder machinery, which simplifies the approach to ensuring superclass instances exist - we just reuse `entails`!