... | ... | @@ -49,13 +49,13 @@ Type function (kind) signatures are represented by the new declaration form `TyF |
|
|
|
|
|
`HsDecls.TyClDecl` has a new variant `TyFunction` to represent signatures of type functions. These consist of the name, type parameters, an iso flag, and optionally an explicit result kind. The type parameters can have kind signatures as usual.
|
|
|
|
|
|
#### Type function equations and definitions of associated data types
|
|
|
#### Type function equations and associated data types
|
|
|
|
|
|
|
|
|
To represent type functions and associated data types, we need to generalise data type declarations `TyData` and type synonym declarations `TySynonym` to allow type patterns instead of just type variables as parameters. We do so by way of the field `tcdPats` of type `Maybe [LHsType name]`, used as follows:
|
|
|
|
|
|
- If it is `Nothing`, we have a *vanilla* data type declaration or type synonym declaration and `tcdVars` contains the type parameters of the type constructor.
|
|
|
- If it is `Just pats`, we have the definition of an associated data type or a type function equations (toplevel or nested in an instance declarations). Then, 'pats' are type patterns for the type-indexes of the type constructor and `tcdVars` are the variables in those patterns. Hence, the arity of the type constructor is `length tcdPats` and \*not\* `length tcdVars`.
|
|
|
- If it is `Just pats`, we have the definition of an associated data type or a type function equations (toplevel or nested in an instance declarations). Then, 'pats' are type patterns for the type-indexes of the type constructor and `tcdVars` are the variables in those patterns. Hence, the arity of the type constructor is `length tcdPats` and *not*`length tcdVars`.
|
|
|
|
|
|
|
|
|
In both cases (and as before type functions), `tcdVars` collects all variables we need to quantify over.
|
... | ... | @@ -84,16 +84,16 @@ GHC is organised such that class and type declarations are processed (during ren |
|
|
|
|
|
---
|
|
|
|
|
|
---
|
|
|
### Renaming and extraction of associated data types
|
|
|
|
|
|
`Revise from here!`
|
|
|
|
|
|
---
|
|
|
During renaming, we enter the names of all data constructors that an associated data type defines into the global `RdrName` environment by extending the function `RnNames.getLocalDeclBinders` such that it traverses instance declarations, too. We are careful not to add the data type constructor multiple times by ignoring them in instance declarations. The global `RdrName` environment only ever contains the type constructor introduced in the class declaration (i.e, the `RdrName` of an associated data type maps to the `Name` of the AT declaration in the class).
|
|
|
|
|
|
### Renaming and extraction of associated data types
|
|
|
---
|
|
|
|
|
|
`Revise from here!`
|
|
|
|
|
|
Before the associated data type declarations are lifted out of the defining instances, we enter the names of all data constructors that an associated data type defines into the global `RdrName` environment by extending the function `RnNames.getLocalDeclBinders` such that it traverses instance declarations, too. We are careful not to add the data type constructor multiple times. In fact, it is ignored in instance declarations. The global `RdrName` environment only ever contains the type constructor introduced in the class declaration (i.e, the `RdrName` of an associated data type maps to the `Name` of the AT declaration in the class).
|
|
|
---
|
|
|
|
|
|
---
|
|
|
|
... | ... | @@ -105,7 +105,7 @@ Before the associated data type declarations are lifted out of the defining inst |
|
|
Now, we can extract the associated data type declarations out of instances in `RnSource.rnSrcDecl`, which is only called by `RnSource.rnSrcDecls`. As part of the extraction process, we also call `RnSource.rnTyClDecl` on each AT declaration to obtain the renamed form of these declarations. We add these renamed forms to the type and class declarations (i.e., `hs_tyclds`) of the currently processed binding group, but also keep a copy in the instance declarations, were they are needed during type checking to perform some well-formedness checks (e.g., that each AT of a class receives a definition). NB: Lifted associated type declarations inherit the context of the instance head. However, the variables of the data declaration are renamed independently of those of the instance head (which implies that the inherited copy of the instance context is renamed again as part of the data declaration).
|
|
|
|
|
|
|
|
|
During renaming, AT declarations in classes are checked for being empty (i.e., no constructors and no context) and for conformance of the type parameters with those of the class. We also check all parameters are type variables, and we inherit kind signatures from the corresponding class parameters (if any of these already have kind signatures, we raise an error) - in fact, we inherit the `Name`s of the class parameters. Afterwards, `tcdTyPats` is reset to `Nothing`.
|
|
|
During renaming, AT declarations are checked for conformance of the type parameters with those of the class. AT declarations inherit kind signatures from the corresponding class parameters (if any of these already have kind signatures, we raise an error) - in fact, we inherit the `Name`s of the class parameters. Moreover, associated data declarations in classes are checked for being empty (i.e., no constructors and no context).
|
|
|
|
|
|
### Type checking associated data types
|
|
|
|
... | ... | |