我在读LYAHFG,但我无法理解 state monad。
在书中,状态单子被定义为
newtype State s a = State { runState :: s -> (a,s) }
instance Monad (State s) where
return x = State $ \s -> (x,s)
(State h) >>= f = State $ \s -> let (a, newState) = h s
(State g) = f a
in g newState
pop :: State Stack Int
pop = State $ \(x:xs) -> (x,xs)
push :: Int -> State Stack ()
push a = State $ \xs -> ((),a:xs)
stackManip :: State Stack Int
stackManip = do
push 3
a <- pop
pop
runState stackManip [5,8,2,1]
Run Code Online (Sandbox Code Playgroud)
这本书通过使用堆栈来解释这一点,其中堆栈是状态,元素是结果。
我的问题特别是如何runState stackManip [5,8,2,1]工作?
runState接受一个论点,这很好,但stackManip不接受任何论点。如何[5,8,2,1]获取初始状态?
runState实际上需要两个参数。当您申报记录时
newtype State s a = State { runState :: s -> (a, s) }
Run Code Online (Sandbox Code Playgroud)
这定义了具有以下签名的函数 runState:
runState :: State s a -> s -> (a, s)
runState (State run) = run
Run Code Online (Sandbox Code Playgroud)
s -> (a, s)在显式操作记录(模式匹配、构造、更新)时,您可以单独获得类型:
pop = State { runState = \(x : s) -> (x, s) }
Run Code Online (Sandbox Code Playgroud)