%
% (c) The University of Glasgow 2006
%
\begin{code}
module Kind (
SuperKind, Kind, typeKind,
anyKind, liftedTypeKind, unliftedTypeKind, openTypeKind, constraintKind,
mkArrowKind, mkArrowKinds,
typeNatKind, typeStringKind,
anyKindTyCon, liftedTypeKindTyCon, openTypeKindTyCon,
unliftedTypeKindTyCon, constraintKindTyCon,
superKind, superKindTyCon,
pprKind, pprParendKind,
kindAppResult, synTyConResKind,
splitKindFunTys, splitKindFunTysN, splitKindFunTy_maybe,
isLiftedTypeKind, isUnliftedTypeKind, isOpenTypeKind,
isConstraintKind, isConstraintOrLiftedKind, returnsConstraintKind,
isKind, isKindVar,
isSuperKind, isSuperKindTyCon,
isLiftedTypeKindCon, isConstraintKindCon,
isAnyKind, isAnyKindCon,
okArrowArgKind, okArrowResultKind,
isSubOpenTypeKind,
isSubKind, isSubKindCon,
tcIsSubKind, tcIsSubKindCon,
defaultKind,
kiVarsOfKind, kiVarsOfKinds
) where
#include "HsVersions.h"
import Type ( typeKind, substKiWith, eqKind )
import TypeRep
import TysPrim
import TyCon
import VarSet
import PrelNames
import Outputable
import Util
\end{code}
%************************************************************************
%* *
Functions over Kinds
%* *
%************************************************************************
\begin{code}
kindFunResult :: Kind -> KindOrType -> Kind
kindFunResult (FunTy _ res) _ = res
kindFunResult (ForAllTy kv res) arg = substKiWith [kv] [arg] res
kindFunResult k _ = pprPanic "kindFunResult" (ppr k)
kindAppResult :: Kind -> [Type] -> Kind
kindAppResult k [] = k
kindAppResult k (a:as) = kindAppResult (kindFunResult k a) as
splitKindFunTys :: Kind -> ([Kind],Kind)
splitKindFunTys (FunTy a r) = case splitKindFunTys r of
(as, k) -> (a:as, k)
splitKindFunTys k = ([], k)
splitKindFunTy_maybe :: Kind -> Maybe (Kind,Kind)
splitKindFunTy_maybe (FunTy a r) = Just (a,r)
splitKindFunTy_maybe _ = Nothing
splitKindFunTysN :: Int -> Kind -> ([Kind],Kind)
splitKindFunTysN 0 k = ([], k)
splitKindFunTysN n (FunTy a r) = case splitKindFunTysN (n1) r of
(as, k) -> (a:as, k)
splitKindFunTysN n k = pprPanic "splitKindFunTysN" (ppr n <+> ppr k)
synTyConResKind :: TyCon -> Kind
synTyConResKind tycon = kindAppResult (tyConKind tycon) (map mkTyVarTy (tyConTyVars tycon))
isOpenTypeKind, isUnliftedTypeKind,
isConstraintKind, isAnyKind, isConstraintOrLiftedKind :: Kind -> Bool
isOpenTypeKindCon, isUnliftedTypeKindCon,
isSubOpenTypeKindCon, isConstraintKindCon,
isLiftedTypeKindCon, isAnyKindCon :: TyCon -> Bool
isLiftedTypeKindCon tc = tyConUnique tc == liftedTypeKindTyConKey
isAnyKindCon tc = tyConUnique tc == anyKindTyConKey
isOpenTypeKindCon tc = tyConUnique tc == openTypeKindTyConKey
isUnliftedTypeKindCon tc = tyConUnique tc == unliftedTypeKindTyConKey
isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey
isAnyKind (TyConApp tc _) = isAnyKindCon tc
isAnyKind _ = False
isOpenTypeKind (TyConApp tc _) = isOpenTypeKindCon tc
isOpenTypeKind _ = False
isUnliftedTypeKind (TyConApp tc _) = isUnliftedTypeKindCon tc
isUnliftedTypeKind _ = False
isConstraintKind (TyConApp tc _) = isConstraintKindCon tc
isConstraintKind _ = False
isConstraintOrLiftedKind (TyConApp tc _)
= isConstraintKindCon tc || isLiftedTypeKindCon tc
isConstraintOrLiftedKind _ = False
returnsConstraintKind :: Kind -> Bool
returnsConstraintKind (ForAllTy _ k) = returnsConstraintKind k
returnsConstraintKind (FunTy _ k) = returnsConstraintKind k
returnsConstraintKind (TyConApp tc _) = isConstraintKindCon tc
returnsConstraintKind _ = False
okArrowArgKindCon, okArrowResultKindCon :: TyCon -> Bool
okArrowArgKindCon kc
| isLiftedTypeKindCon kc = True
| isUnliftedTypeKindCon kc = True
| isConstraintKindCon kc = True
| otherwise = False
okArrowResultKindCon = okArrowArgKindCon
okArrowArgKind, okArrowResultKind :: Kind -> Bool
okArrowArgKind (TyConApp kc []) = okArrowArgKindCon kc
okArrowArgKind _ = False
okArrowResultKind (TyConApp kc []) = okArrowResultKindCon kc
okArrowResultKind _ = False
isSubOpenTypeKind :: Kind -> Bool
isSubOpenTypeKind (TyConApp kc []) = isSubOpenTypeKindCon kc
isSubOpenTypeKind _ = False
isSubOpenTypeKindCon kc
= isOpenTypeKindCon kc
|| isUnliftedTypeKindCon kc
|| isLiftedTypeKindCon kc
|| isConstraintKindCon kc
isKind :: Kind -> Bool
isKind k = isSuperKind (typeKind k)
isSubKind :: Kind -> Kind -> Bool
isSuperKindTyCon :: TyCon -> Bool
isSuperKindTyCon tc = tc `hasKey` superKindTyConKey
isSubKind (FunTy a1 r1) (FunTy a2 r2)
= (isSubKind a2 a1) && (isSubKind r1 r2)
isSubKind k1@(TyConApp kc1 k1s) k2@(TyConApp kc2 k2s)
| isPromotedTyCon kc1 || isPromotedTyCon kc2
= eqKind k1 k2
| isSuperKindTyCon kc1 || isSuperKindTyCon kc2
= ASSERT2( isSuperKindTyCon kc2 && isSuperKindTyCon kc2
&& null k1s && null k2s,
ppr kc1 <+> ppr kc2 )
True
| otherwise =
ASSERT2( null k1s && null k2s, ppr k1 <+> ppr k2 )
kc1 `isSubKindCon` kc2
isSubKind k1 k2 = eqKind k1 k2
isSubKindCon :: TyCon -> TyCon -> Bool
isSubKindCon kc1 kc2
| kc1 == kc2 = True
| isOpenTypeKindCon kc2 = isSubOpenTypeKindCon kc1
| otherwise = False
tcIsSubKind :: Kind -> Kind -> Bool
tcIsSubKind k1 k2
| isConstraintKind k1 = isConstraintKind k2
| otherwise = isSubKind k1 k2
tcIsSubKindCon :: TyCon -> TyCon -> Bool
tcIsSubKindCon kc1 kc2
| isConstraintKindCon kc1 = isConstraintKindCon kc2
| otherwise = isSubKindCon kc1 kc2
defaultKind :: Kind -> Kind
defaultKind (TyConApp kc _args)
| isOpenTypeKindCon kc = ASSERT( null _args ) liftedTypeKind
defaultKind k = k
kiVarsOfKind :: Kind -> VarSet
kiVarsOfKind = tyVarsOfType
kiVarsOfKinds :: [Kind] -> VarSet
kiVarsOfKinds = tyVarsOfTypes
\end{code}