be true about it. We don't want to perform these checks at the same time
as the initial translation because (a) they are unnecessary for interface-file
types and (b) when checking a mutually recursive group of type and class decls,
-we can't "look" at the tycons/classes yet.
+we can't "look" at the tycons/classes yet. Also, the checks are are rather
+diverse, and used to really mess up the other code.
One thing we check for is 'rank'.
r1 ::= forall tvs. cxt => r0
r0 ::= r0 -> r0 | basic
+Another thing is to check that type synonyms are saturated.
+This might not necessarily show up in kind checking.
+ type A i = i
+ data T k = MkT (k Int)
+ f :: T A -- BAD!
+
\begin{code}
data UserTypeCtxt
= FunSigCtxt Name -- Function type signature
1. Kind check the HsType [kcHsType]
2. Convert from HsType to Type, and hoist the foralls [tcHsType]
- 3. Check the validity of the resultint type [checkValidType]
+ 3. Check the validity of the resulting type [checkValidType]
Often these steps are done one after the othe (tcHsSigType).
But in mutually recursive groups of type and class decls we do
ATyVar tv -> returnTc (mkAppTys (mkTyVarTy tv) arg_tys)
AGlobal (ATyCon tc)
- | isSynTyCon tc -> returnTc (mkAppTys (mkSynTy tc (take arity arg_tys))
- (drop arity arg_tys))
+ | isSynTyCon tc -> returnTc (mkSynTy tc arg_tys)
| otherwise -> returnTc (mkTyConApp tc arg_tys)
- where
- arity = tyConArity tc
-
other -> failWithTc (wrongThingErr "type constructor" thing name)
\end{code}
~~~~~
\begin{code}
-mkSynTy syn_tycon tys
- = ASSERT( isSynTyCon syn_tycon )
- ASSERT( length tyvars == length tys )
- NoteTy (SynNote (TyConApp syn_tycon tys))
- (substTyWith tyvars tys body)
+mkSynTy tycon tys
+ | n_args == arity -- Exactly saturated
+ = mk_syn tys
+ | n_args > arity -- Over-saturated
+ = foldl AppTy (mk_syn (take arity tys)) (drop arity tys)
+ | otherwise -- Un-saturated
+ = TyConApp tycon tys
+ -- For the un-saturated case we build TyConApp directly
+ -- (mkTyConApp ASSERTs that the tc isn't a SynTyCon).
+ -- Here we are relying on checkValidType to find
+ -- the error. What we can't do is use mkSynTy with
+ -- too few arg tys, because that is utterly bogus.
+
where
- (tyvars, body) = getSynTyConDefn syn_tycon
+ mk_syn tys = NoteTy (SynNote (TyConApp tycon tys))
+ (substTyWith tyvars tys body)
+
+ (tyvars, body) = ASSERT( isSynTyCon tycon ) getSynTyConDefn tycon
+ arity = tyConArity tycon
+ n_args = length tys
\end{code}
Notes on type synonyms