packages feed

lambda-cube-0.3.0.0: src/LambdaCube/SystemF/TypeChecker.hs

module LambdaCube.SystemF.TypeChecker
  ( infer
  ) where

import           Data.List                       (uncons)
import           LambdaCube.SystemF.Ast
import           LambdaCube.SystemF.Substitution

infer :: LCTerm -> LCType
infer = go []
  where
    go tl (LCVar x) = maybe (error "Out-of-scope variable") fst . uncons $ drop x tl
    go tl (LCLam t b) = t `LCArr` go (t : tl) b
    go tl (LCApp f a)
      | LCArr at rt <- go tl f
      , at == go tl a
      = rt
      | otherwise
      = error "Function argument type mismatch"
    go tl (LCTLam b) = LCUniv $ go (fmap (shiftType . (, 1)) tl) b
    go tl (LCTApp f t)
      | LCUniv rt <- go tl f
      = substituteTypeInType t 0 rt
      | otherwise
      = error "Function argument type mismatch"