lambda-calculator-3.0.0: src/Language/Lambda/SystemF/State.hs
module Language.Lambda.SystemF.State
( TypecheckState(..),
Typecheck(),
Context(),
runTypecheck,
execTypecheck,
unsafeRunTypecheck,
unsafeExecTypecheck,
mkTypecheckState,
context,
uniques,
getContext,
getUniques,
modifyContext,
modifyUniques,
setContext,
setUniques
) where
import Language.Lambda.Shared.Errors (LambdaException(..))
import Language.Lambda.SystemF.Expression (Ty(..))
import Control.Monad.Except (Except(), runExcept)
import RIO
import RIO.State
import qualified RIO.Map as Map
data TypecheckState name = TypecheckState
{ tsContext :: Context name,
tsUniques :: [name]
}
type Typecheck name
= StateT (TypecheckState name)
(Except LambdaException)
type Context name = Map name (Ty name)
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] -> TypecheckState name
mkTypecheckState = TypecheckState Map.empty
uniques :: Lens' (TypecheckState name) [name]
uniques f state' = (\uniques' -> state' { tsUniques = uniques' })
<$> f (tsUniques state')
context :: Lens' (TypecheckState name) (Context name)
context f state' = (\context' -> state' { tsContext = context' })
<$> f (tsContext state')
getUniques :: Typecheck name [name]
getUniques = gets (^. uniques)
getContext :: Typecheck name (Context name)
getContext = gets (^. context)
modifyContext :: (Context name -> Context name) -> Typecheck name ()
modifyContext f = modify $ context %~ f
modifyUniques :: ([name] -> [name]) -> Typecheck name ()
modifyUniques f = modify $ uniques %~ f
setUniques :: [name] -> Typecheck name ()
setUniques uniques' = modify (& uniques .~ uniques')
setContext :: Context name -> Typecheck name ()
setContext context' = modify (& context .~ context')