2016-05-06 8 views
0
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() 

問題をより明確にするためにコード全体を入れない。 そして、私はhandleFCallinterpreter statementsの関数でReader monad(私は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

注: '>> = \ _ - > ..'は'> 'と同じですが、コードを読みやすくするために80字以下の長さの文字列を使用することをお勧めします。 – epsilonhalbe

+0

また、 'local(\ _ - > ...)ask'は何もしません。環境は 'ask'のためだけに変更されています。私の答えはその例を見てください。 – ErikR

答えて

1

local機能を使用します。ここでは簡単な例です:exampleを実行しているから

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) 

出力:

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") 

当初はリーダーの環境が13であるlocal (+20)コールは13 + 20に設定するリーダー環境でfoo 2を実行します。次に、Reader環境を42に設定してfoo 3を実行します。最後に、foo 4が元の環境で実行されます。

関連する問題