【发布时间】:2016-10-01 14:24:28
【问题描述】:
我是 Haskell 的初学者,我遇到了一个我想使用 state monad 的情况。 (或者至少,我认为这就是我想要使用的。)状态单子有一百万个教程,但它们似乎都假设我的主要目标是在更深的概念层面上理解它,并且因此,他们就在他们说如何用它实际开发软件的部分之前停下来。所以我正在寻求一个简化的实际示例的帮助。
下面是我当前代码的一个非常简单的版本。如您所见,我正在通过我的函数线程化状态,我的问题只是如何使用do 符号重写代码,这样我就不必这样做了。
data Machine = Register Int
addToState :: Machine -> Int -> Machine
addToState (Register s) a = Register $ s+a
subtractFromState :: Machine -> Int -> Machine
subtractFromState (Register s) a = Register (s-a)
getValue :: Machine -> Int
getValue (Register s) = s
initialState = Register 0
runProgram = getValue (subtractFromState (addToState initialState 6) 4)
该代码模拟了一个简单的抽象机器,它有一个寄存器,以及对寄存器进行加法、减法和获取值的指令。最后的“程序”将寄存器初始化为0,加6,减4,返回结果,当然是2。
我理解 state monad 的目的(或者至少我认为我理解),并且我希望它允许我重新编写它,以便我最终得到类似的东西
runProgram :: ???????
runProgram = do
put 0
addToState 6
subtractFromState 4
value <- getValue
return value
但是,尽管我阅读了所有教程,但我仍然不太清楚如何将我的代码转换为这种形式。
当然,我的实际机器的状态要复杂得多,而且我也在传递它的输出(将传递给另一台机器)和其他各种东西,所以我非常热衷于简化它。知道如何为这个简化的示例执行此操作将非常有帮助。
更新:在 Lee 的出色回答之后,我现在知道如何做到这一点,但是当我有多个交互机器时,我被困在如何以同样优雅的形式编写代码。我在a new question 中问过这个问题。
【问题讨论】:
标签: haskell monads state-monad