Open gelisam opened 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.
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.