packages feed

inch-0.1.0: src/Language/Inch/KindCheck.lhs

> {-# LANGUAGE TypeOperators, GADTs #-}

> module Language.Inch.KindCheck where

> import Control.Applicative
> import Data.Traversable

> import Language.Inch.BwdFwd
> import Language.Inch.Kind
> import Language.Inch.Type
> import Language.Inch.Context
> import Language.Inch.Kit
> import Language.Inch.Error

> inferKind :: Binder -> Bwd (Ex (Var ())) -> SType -> Contextual TyKind
> inferKind b g (STyVar x)   = (\ (Ex v) -> TK (TyVar v) (varKind v)) <$> lookupTyVar b g x
> inferKind _ _ (STyCon c)   = (\ (Ex k) -> TK (TyCon c k) k) <$> lookupTyCon c
>                            <|> (\ (Ex t) -> case getTySynKind t of
>                                          k -> TK (TySyn c t) k) <$> lookupTySyn c
> inferKind b g (STyApp f s)  = do
>     TK f' k  <- inferKind b g f
>     case k of
>         k1 :-> k2 -> do
>             TK s' l  <- inferKind b g s
>             hetEq k1 l
>                 (return $ TK (TyApp f' s') k2)
>                 (errKindMismatch (s ::: fogKind l) (fogKind k1))
>             
>         _ -> errKindNotArrow (fogKind k)
> inferKind _ _ SArr         = return $ TK Arr (KSet :-> KSet :-> KSet)
> inferKind _ _ (STyInt i)   = return $ TK (TyInt i) KNum
> inferKind _ _ (SUnOp o)    = return $ TK (UnOp o) (KNum :-> KNum)
> inferKind _ _ (SBinOp o)   = return $ TK (BinOp o) (KNum :-> KNum :-> KNum)
> inferKind _ _ (STyComp c)  = return $ TK (TyComp c) (KNum :-> KNum :-> KConstraint)
> inferKind b g (SBind c a SKNat t)  = do
>     v <- freshVar (UserVar All) a KNum
>     ty <- checkKind KSet b (g :< Ex v) t
>     return $ TK (Bind c a KNum (bindTy v (Qual (tyPred LE 0 (TyVar v)) ty))) KSet
> inferKind b g (SBind c a k t)  = case kindKind k of
>     Ex k' -> do
>         v <- freshVar (UserVar All) a k'
>         ty <- checkKind KSet b (g :< Ex v) t
>         return $ TK (Bind c a k' (bindTy v ty)) KSet
> inferKind b g (SQual p t) = do
>     p' <- checkKind KConstraint b g p
>     TK t' KSet <- inferKind b g t
>     return $ TK (Qual p' t') KSet


> checkKind :: Kind k -> Binder -> Bwd (Ex (Var ())) -> SType -> Contextual (Type k)
> checkKind k b g t = do
>   TK t' k' <- inferKind b g t
>   hetEq k k' (return t')
>              (errKindMismatch (fogTy t' ::: fogKind k') (fogKind k))

> checkPredKind :: Binder -> Bwd (Ex (Var ())) -> SPredicate -> Contextual Predicate
> checkPredKind b g = traverse (checkKind KNum b g)