gelisam / klister

an implementation of stuck macros
BSD 3-Clause "New" or "Revised" License
130 stars 11 forks source link

type classes #167

Open gelisam opened 1 year ago

gelisam commented 1 year ago

We would like to implement type classes as a #lang feature, not as a builtin. We suspect this will require adding a number of builtins to Klister, which will hopefully be useful to implement a lot more than just type classes.

gelisam commented 1 year ago

With #168, a typeclass declaration would create an LVar of instances, an instance declaration would add that instance to the LVar, and method calls would do a threshold read on that LVar, waiting until the instance for the inferred type has been added.

But wait! An instance is not defined by a symbol, so what key does it add to the Map Symbol value? Solution: the outermost type constructor, e.g for instance (C1 a, C2 b) => C (Either a b), the key would be Either. The rest would be stored in the value.

But wait! Which symbol should the method lookup in the case of a polymorphic function like nub :: Eq a => [a] -> [a]? The macro can't discover that the type at which (==) is called is a, because the unification variable ?1 will not become a until after typechecking completes and Hindley-Milner discovers that the type variable is unused. Solution: don't look it up yet, add a dictionary argument of type Eq ?1 and let Hindley-Milner figure out whether ?1 is a type variable or a concrete type. Then, using #159, examine the inferred type and fill-in any dictionary which uses a concrete type rather than a type variable.