... | @@ -34,3 +34,21 @@ Restrictions: |
... | @@ -34,3 +34,21 @@ Restrictions: |
|
|
|
|
|
- We currently don't allow associated GADTs. I cannot see any fundamental problem in supporting them, but I want to keep it simple for the moment. (When allowing this, a constructor signature in an associated GADT can of course only refine the instantiation of the type arguments specific to the instance in which the constructor is defined.)
|
|
- We currently don't allow associated GADTs. I cannot see any fundamental problem in supporting them, but I want to keep it simple for the moment. (When allowing this, a constructor signature in an associated GADT can of course only refine the instantiation of the type arguments specific to the instance in which the constructor is defined.)
|
|
- We currently don't have toplevel data definitions with type patterns. They would essentially be open GADTs, which we probably can type check with the existing GADT machinery and translate much as we translate associated data types in classes. Again, I want to avoid doing too much in the first sweep.
|
|
- We currently don't have toplevel data definitions with type patterns. They would essentially be open GADTs, which we probably can type check with the existing GADT machinery and translate much as we translate associated data types in classes. Again, I want to avoid doing too much in the first sweep.
|
|
|
|
|
|
|
|
## How It Works
|
|
|
|
|
|
|
|
### Type declarations in classes and indexed types
|
|
|
|
|
|
|
|
|
|
|
|
Adding types declarations to classes is fairly straight forward. The `ClassDecl` variant of `TyClDecl` gets a new field `tcdATs`, which contains a list of type declarations - currently, the parser will only allow data type declarations. Similarly, `InstDecl` gets a fourth argument, which is a list of type declarations.
|
|
|
|
|
|
|
|
|
|
|
|
More tricky is the addition of type indexes (i.e., non-type variable arguments) to data type declarations. The grammar is already very general and allows arbitrary arguments, but the parser uses `RdHsSyn.checkTyClHdr` to construct the AST and that function ensures that only type variables are supplied. The new story is that `checkTyClHdr` can operate in two different modes: (1) checking mode and (2) extraction mode. Checking mode corresponds to the original behaviour. In extraction mode, all free type variables of the arguments will be collected, but we don't enforce that the arguments are themselves merely type variables. When processing class headers (and for the moment also type synonyms), we use `checkTyClHdr` in checking mode as before. However, when processing a data type (or newtype) declaration, we use extraction mode and keep both the list of type variables (as `tcdTyVars`) and the original arguments (as `tcdTyPats`) in the representation of data type declarations (i.e., in the variant `TyData` of `TyClDecl`). The check enforcing that all arguments to top-level data type declarations and the non-class parameter arguments of associated data types are variables is delayed until the renamer (as we need context information). In the renamer, we check that non-variable type parameters can only occur in the first few arguments of ATs and we remove these parameters by floating the associated data type declarations to the top-level.
|
|
|
|
|
|
|
|
|
|
|
|
In the parser, we put the original type terms specified as parameters in the field `tcdTyPats`. For top-level declarations, after checking that the parameters are all plain type variables (possibly with a kind signature), we reset `tcdTyPats` to `Nothing` (this already happens during AST construction). `DataDecls` created during parsing Core are already born with `tcdTyPats` being Nothing. (Although, the latter may change.)
|
|
|
|
|
|
|
|
### Phasing
|
|
|
|
|
|
|
|
|
|
|
|
GHC is organised such that class and type declarations are processed (during renaming and type checking) before any instance declarations are considered. The problem now is that instance declarations may contain type declarations; hence, anything that may depend on a type declaration can now also depend on an instance declaration. We solve that by lifting associated data types out of instances before renaming (and hence also before type checking of type and class declarations). |