type InterpreterMonad = StateT (MEMORY, FUNCTIONS) (ReaderT (NameAddress, NameAddress) (ErrorT String IO))
interpreteStmt :: Stmt -> InterpreterMonad ()
handleFCall :: VarName -> [CallArg] -> InterpreterMonad ()
handleFCall (VarName name) argsCall = do
(memory, functions) <- get
case (Map.lookup (VarName name) functions) of
Nothing -> throwError $ "error"
(Just ((DefFun varname argsDef typ begin statements end), env)) -> (checkCoherenceTypesArgs varname argsDef argsCall) >>= \_ -> argsToContext argsDef argsCall env >>= \_ -> interpreter statements >>= \_ -> return ()
我没有提供完整的代码来让我的问题更加清晰。
现在,我想在handleFCall
interpreter statements
函数中修改Reader monad(我的意思是读者中的环境)。怎么做?
P.S。我的尝试:(它没有用,请解释原因)
argsToContext :: [DefArg] -> [CallArg] -> NameAddress -> InterpreterMonad ()
argsToContext xs ys env = do
(memory, fs) <- get
(mem, args) <- (argsToContext' xs ys memory Map.empty)
put ( mem, fs)
throwError $ "Tutej " ++ (show args) ++ " memory " ++ (show mem)
local (\_ -> (env, args)) ask
return ()
答案 0 :(得分:1)
您使用local
功能。这是一个简短的例子:
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Except
type MyMonad = StateT String (ReaderT Int (ExceptT String IO))
foo :: Int -> MyMonad ()
foo x = do
env <- ask
liftIO $ putStrLn $ "x = " ++ show x ++ " and env is: " ++ show env
t1 :: MyMonad ()
t1 = do
foo 1 -- env = 13
local (+20) $ foo 2 -- env = 20+13 = 33
local (const 42) $ foo 3 -- env = 42
foo 4 -- env = 13
example = runExceptT (runReaderT (runStateT t1 "some state") 13)
运行example
的输出:
x = 1 and env is: 13
x = 2 and env is: 33
x = 3 and env is: 42
x = 4 and env is: 13
Right ((),"some state")
最初,Reader环境为13. local (+20)
调用执行foo 2
,Reader环境设置为13 + 20。然后在Reader环境设置为42的情况下执行foo 3
。最后,在原始环境中执行foo 4
。