Monad State并获得功能

时间:2016-04-26 19:06:42

标签: haskell

type InterpreterMonad  = StateT (Env, Env) (ErrorT String IO ) ()    

interpreter :: Stmts -> InterpreterMonad
interpreter (Statements s EmptyStmts) = interpreteStmt s
interpreter (Statements s stmts) = interpreteStmt s >>= \m -> (interpreter stmts)


-- definicja funkcji

interpreteStmt :: Stmt -> InterpreterMonad 
interpreteStmt (DefFun  (VarName name) args typ begin statements end) = get >>= 
    \(envOut, (sInnerEnvFun, sInnerEnvEVal)) -> case (Map.lookup (VarName name) sInnerEnvFun) of
        Nothing -> put ( ( envOut, ((Map.insert (VarName name) (DefFun  (VarName name) args typ begin statements end) sInnerEnvFun), sInnerEnvEVal)) ) >>= \_ -> return ()
        (Just x) -> throwError  "ee"

嗨,我无法理解为什么可以调用getput函数? Haskell如何知道“哪里”是状态?我有一个支持命令式编程的问题 - 毕竟,我们必须调用对象(作为方法)或通过参数传递状态。

2 个答案:

答案 0 :(得分:1)

当您使用State monad函数getput并使用do表示法或>>=对其进行排序时,您正在构建一个"配方" (通常称为"动作")用于访问和修改最终将与某个特定状态一起使用的本地状态。例如:

increment = do
  count <- get
  put (count + 1)

然后,此操作可以与State接口的一部分一起使用,该部分允许您通过传入状态来运行操作。我们将使用execState来返回状态并丢弃其他值,以演示:

> execState increment 1
2

execState是将动作increment与其修改的状态相关联的内容。 increment本身并不包含任何状态,它只是与状态交互的一种方法,您必须在以后进行评估。

答案 1 :(得分:1)

State类型(StateT是一个概括)实现如下:

newtype State s a = 
    State { -- A function that takes a state of type `s` and 
            -- produces a pair `(a, s)` of a result of type 
            -- `a` and a new state of type `s`.
            runState :: s -> (a, s) 
          }

此类型包含FunctorApplicativeMonad的实例,允许您从较简单的值中汇总复杂的State值:

-- I won't write the code for these here
instance Functor (State s) where ...
instance Applicative (State s) where ...
instance Monad (State s) where ...

基本上,State是链接类似s -> (a, s)类型函数的快捷方式,但不必明确传递这些s值。当你准备好实际&#34;饲料&#34; State值为s的{​​{1}}操作您使用其中一项操作(取决于您想要的结果部分):

runState  :: State s a -> s -> (a, s)
evalState :: State s a -> s -> a
execState :: State s a -> s -> s

然后,putget会与&#34;隐藏&#34;进行互动。状态参数,State类型在代码中隐式传递。他们的实现是这样的:

get :: State s s
get = State (\s -> (s, s))

put :: s -> State s ()
put s = State (\_ -> ((), s))

那就是它!