我试图理解以下代码中发生的情况,代码行为正常,但我试图理解为什么。
import Control.Monad.State
import System.IO
import System.Environment
echoArgs :: [String] -> State Int [String]
echoArgs x = loopArgs x >> return x
where loopArgs [] = return ()
loopArgs s@(x':xs') = modify (+1) >> loopArgs xs'
main :: IO ()
main = do
argv <- getArgs
let s = echoArgs argv
mapM_ putStr' (evalState s 0)
putStrLn $ "\nNum Args = " ++ show (execState s 0)
where putStr' x = putStr $ x ++ " "
我不理解的是为什么州议会的州不会重置&#39;每次连续调用loopArgs。状态是否作为变量传递,每个>>
如果有,有人可以告诉我如何?
答案 0 :(得分:3)
确实如此。查看State monad的玩具实现是有帮助的。状态是否作为变量传递,每个&gt;&gt;若有,有人可以告诉我怎么做?
newtype State s a = State { runState :: s -> (a,s) }
instance Monad (State s) where
return a = State $ \s -> (a, s)
State act >>= k = State $ \s ->
let (a, s') = act s
in runState (k a) s'
get :: State s s
get = State $ \s -> (s, s)
put :: s -> State s ()
put s = State $ \_ -> ((), s)
modify :: (s -> s) -> State s ()
modify f = get >>= \x -> put (f x)
使用>>=
或>>
进行绑定时,累积状态将作为右侧函数的参数进行操作。
当您运行execState
或evalState
时,它只会从结果元组中提取结果值或状态。
execState :: State s a -> s -> s
execState act = snd . runState act
evalState :: State s a -> s -> a
evalState act = fst . runState act