lambda-calculator-3.1.0.0: src/Language/Lambda/SystemF/State.hs
module Language.Lambda.SystemF.State
( TypecheckState(..),
Typecheck(),
Context(),
Binding(..),
Globals(),
runTypecheck,
execTypecheck,
unsafeRunTypecheck,
unsafeExecTypecheck,
mkTypecheckState,
_context,
_globals,
_varUniques,
_tyUniques,
getContext,
getGlobals,
getVarUniques,
getTyUniques,
modifyGlobals,
modifyVarUniques,
modifyTyUniques,
setGlobals,
setVarUniques,
setTyUniques
) where
import Language.Lambda.Shared.Errors (LambdaException(..))
import Language.Lambda.SystemF.Expression
import Control.Monad.Except (Except(), runExcept)
import RIO
import RIO.State
import qualified RIO.Map as Map
data TypecheckState name = TypecheckState
{ tsGlobals :: Globals name,
tsVarUniques :: [name], -- ^ A unique supply of term-level variables
tsTyUniques :: [name] -- ^ A unique supply of type-level variables
} deriving (Eq, Show)
type Typecheck name
= StateT (TypecheckState name)
(Except LambdaException)
type Globals name = Map name (TypedExpr name)
type Context name = Map name (Binding name)
data Binding name
= BindTerm (Ty name)
| BindTy
deriving (Eq, Show)
runTypecheck
:: Typecheck name result
-> TypecheckState name
-> Either LambdaException (result, TypecheckState name)
runTypecheck computation = runExcept . runStateT computation
execTypecheck
:: Typecheck name result
-> TypecheckState name
-> Either LambdaException result
execTypecheck computation = runExcept . evalStateT computation
unsafeRunTypecheck
:: Typecheck name result
-> TypecheckState name
-> (result, TypecheckState name)
unsafeRunTypecheck computation state' = either impureThrow id tcResult
where tcResult = runTypecheck computation state'
unsafeExecTypecheck :: Typecheck name result -> TypecheckState name -> result
unsafeExecTypecheck computation state' = either impureThrow id tcResult
where tcResult = execTypecheck computation state'
mkTypecheckState :: [name] -> [name] -> TypecheckState name
mkTypecheckState = TypecheckState Map.empty
_context :: SimpleGetter (TypecheckState name) (Context name)
_context = to (getContext' . tsGlobals)
where getContext' :: Globals name -> Context name
getContext' = Map.map (\expr -> BindTerm (expr ^. _ty))
_globals :: Lens' (TypecheckState name) (Globals name)
_globals f state' = (\globals' -> state' { tsGlobals = globals' })
<$> f (tsGlobals state')
_varUniques :: Lens' (TypecheckState name) [name]
_varUniques f state' = (\uniques' -> state' { tsVarUniques = uniques' })
<$> f (tsVarUniques state')
_tyUniques :: Lens' (TypecheckState name) [name]
_tyUniques f state' = (\uniques' -> state' { tsTyUniques = uniques' })
<$> f (tsTyUniques state')
getVarUniques :: Typecheck name [name]
getVarUniques = gets (^. _varUniques)
getTyUniques :: Typecheck name [name]
getTyUniques = gets (^. _tyUniques)
getContext :: Typecheck name (Context name)
getContext = gets (^. _context)
getGlobals :: Typecheck name (Globals name)
getGlobals = gets (^. _globals)
modifyGlobals :: (Globals name -> Globals name) -> Typecheck name ()
modifyGlobals f = modify $ _globals %~ f
modifyVarUniques :: ([name] -> [name]) -> Typecheck name ()
modifyVarUniques f = modify $ _varUniques %~ f
modifyTyUniques :: ([name] -> [name]) -> Typecheck name ()
modifyTyUniques f = modify $ _tyUniques %~ f
setVarUniques :: [name] -> Typecheck name ()
setVarUniques uniques' = modify $ _varUniques .~ uniques'
setTyUniques :: [name] -> Typecheck name ()
setTyUniques uniques' = modify $ _tyUniques .~ uniques'
setGlobals :: Globals name -> Typecheck name ()
setGlobals globals' = modify $ _globals .~ globals'