registry-0.1.0.0: src/Data/Registry/Internal/Stack.hs
{- |
Internal monad for the resolution algorithm
- we keep some state for the list of created values
- we collect the applied functions as "Operations"
- we might exit with a Left value if we can't build a value
-}
module Data.Registry.Internal.Stack where
import Data.Registry.Internal.Operations
import Data.Registry.Internal.Types
import Protolude
-- | Monadic stack for the resolution algorithm
type Stack a = StateT (Values, Operations) (Either Text) a
-- | Return a value from the Stack if possible
runStack :: Stack a -> Values -> Either Text a
runStack sa vs = evalStateT sa (vs, [])
-- | Return the state of the stack after executing the action
-- This returns the list of built values
execStack :: Stack a -> Values -> Either Text Values
execStack sa vs = fst <$> execStateT sa (vs, [])
-- | Return the list of applied functions after resolution
evalStack :: Stack a -> Values -> Either Text Operations
evalStack sa vs = snd <$> execStateT sa (vs, [])
-- | Get the current list of values
getValues :: Stack Values
getValues = fst <$> get
-- | Get the current list of operations
getOperation :: Stack Operations
getOperation = snd <$> get
-- | Modify the current list of values
modifyValues :: (Values -> Values) -> Stack ()
modifyValues f = modify (\(vs, ops) -> (f vs, ops))
-- | Get the current list of values
modifyOperations :: (Operations -> Operations) -> Stack ()
modifyOperations f = modify (\(vs, ops) -> (vs, f ops))
-- | Store a function application in the list of operations
functionApplied :: Value -> [Value] -> Stack ()
functionApplied output inputs = modifyOperations (AppliedFunction output inputs:)