haskell - State Monad 是如何获取初始状态的?
问题描述
我正在阅读LYAHFG,但我无法理解状态单子。
在书中,状态单子被定义为
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]
本书通过使用堆栈来解释这一点,其中堆栈是状态,元素是结果。
我的问题特别是如何runState stackManip [5,8,2,1]
工作?
runState
接受一个论点,这很好,但stackManip
不接受任何论点。初始状态如何[5,8,2,1]
获取?
解决方案
runState
实际上需要两个参数。当您申报记录时
newtype State s a = State { runState :: s -> (a, s) }
这定义了具有以下签名的函数: runState
runState :: State s a -> s -> (a, s)
runState (State run) = run
s -> (a, s)
当显式操作记录(模式匹配、构造、更新)时,您可以单独获得类型:
pop = State { runState = \(x : s) -> (x, s) }
推荐阅读
- java - 使用传递给模拟对象的函数进行测试
- javascript - 如何填充数组中的值
- java - String.isBlank() 替换
- oracle - 将 VArray 连接到 String 并在动态 SQL 中使用 - Oracle
- javascript - 已解决:如何从 Wordpress 中删除“js.donatelloflowfirstly.ga”?
- sharepoint - Sharepoint 工作流分配电子邮件不保留查找
- java - android gradle 如何将构建版本传递给 android mk
- azure - 为什么在日志中我可以看到“[39m[38 5”到处都是(天蓝色日志分析)?这是什么意思?
- c# - 重新设置单例httpclient的证书(重新配置IHttpclientFactory?)
- javascript - 如何迭代所有子元素并返回找到的元素?