Note [kcConDecls: kind-checking data type decls]
kcConDecls is used when we are inferring the kind of the type constructor in a data type declaration. The basic plan is described in Note [Inferring kinds for type declarations]; here we are doing Step 2. We are kind-checking the data constructors /only/ to compute the kind of the type construtor. For example data T f a = MkT (f a) The (f a) in the data construtor constrains the kinds of `f` and `a`, and hence of `T`. There are two cases to consider in `kcConDecl` * Haskell 98 data constructors, as above. We simply bring `f` and `a` into scope and kind-check the data constructors. * GADT data type decls e.g. data S f a where MkS :: g b -> S g b Here `f` and `a` don't scope over the data constructor signatures. Instead, we just kind-check the entire signature (including the result `S g b`), relying on the fact that `S` is in scope with its initial kind `k1 -> k2 -> Type`; doing so will constrain `k1` and `k2` appropriately. The arguments of each data constructor are always of kind (TYPE r) for some r :: RuntimeRep. But in the case of a newytype, the argument kind must be the same as the tycon result kind. Since we are trying to figure out the tycon kind, kcConDecls must account for this, which is surprisingly tricky. Again there are two cases to consider in `kcConDecl`: * Haskell 98 data type decls, e.g. data T f a = MkT (f a) * In the header, all the tycon binders are specified (here `f` and `a`) and there is no result kind signature. * The binders from the header scope over the data construtors. * In the case of unlifted newtypes, the argument kind affects the tycon kind newtype N = MkN Int# Here `getInitialKind` will give `N` the result kind `TYPE r`, where `r` is a unification variable, and `kcConDecls` should unify that `r` with `IntRep` becuase of the `Int#` Solution (KCD1): just check that the argumet type has the same kind as the result kind of the tycon. * GADT data type decls e.g. data S f :: Type -> Type where MkS :: g a -> S g a * In the header, not all the tycon binders are specified (here just `f`), and there can be a kind signature * The kind signature may describe some, all, or none of the tycon binders. Regardless, in the TcTyCon constructed by `getInitialKind`, the tyConResKind is the signature, not the "ultimate" result type of the tycon (which is usually Type) * In the case of unlifted newtypes, we again want the argument kind to be the same as the result kind of the tycon; but it's not so clear what /is/ the result kind of the tycon, because of the signature stuff in the previous bullet. Solution (KCD2): kind-check the result type of the data constructor (here `S g a`) and, for newtypes, ensure that the arugment has that same kind. (KCD3) The tycon's result kind `tc_res_kind` is not used at all in the GADT case; rather it is accessed via looking up S's kind in the type environment when kind-checking the result type of the data constructor.
References 1
- Inferring kinds for type declarations GHC.Tc.TyCl
Referenced by 5
- GHC.Tc.TyCl call site ×5