2016-05-06 16 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() 

Ich nicht ganzen Code setzen, um mein Problem klarer zu machen. Und jetzt möchte ich Reader Monad (ich meine Umgebung in Reader) in handleFCall Funktion für interpreter statements ändern. Wie es geht?Monad Stack und modifizieren Leser Umgebung

P.S. Mein Versuch: (Es funktioniert nicht, bitte zu erklären, warum)

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

hinweis: '>> = \ _ -> ..' ist das gleiche wie' >> ', auch ist es ratsam, um eine Zeile Länge von mehr oder weniger 80 Zeichen zu halten, um Ihren Code lesbar zu machen. – epsilonhalbe

+0

Beachten Sie auch, dass 'local (\ _ -> ...) ask 'nichts bewirkt. Die Umgebung wird nur für das 'ask' modifiziert - nach der Rückkehr wird die Leserumgebung sozusagen" wiederhergestellt ". Siehe meine Antwort für ein Beispiel dafür. – ErikR

Antwort

1

Sie verwenden die local Funktion. Hier ist ein kurzes Beispiel:

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) 

Ausgabe vom Laufen 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") 

Zunächst wird die Reader-Umgebung ist 13. Der local (+20) Aufruf foo 2 mit der Reader-Umgebung 13 + 20 gesetzt ausführt. Dann wird foo 3 mit der auf 42 eingestellten Reader-Umgebung ausgeführt. Schließlich wird foo 4 in der ursprünglichen Umgebung ausgeführt.