相关疑难解决方法(0)

模拟Haskell中的交互状态对象

我正在编写一个Haskell程序,它涉及模拟一个抽象机器,它具有内部状态,接受输入并提供输出.我知道如何使用状态monad实现这一点,从而产生更清晰,更易于管理的代码.

我的问题是,当我有两个(或更多)有状态对象相互交互时,我不知道如何使用相同的技巧.下面我给出了一个高度简化的问题版本,并勾勒出我到目前为止的内容.

为了这个问题,让我们假设一个机器的内部状态只包含一个整数寄存器,因此它的数据类型是

data Machine = Register Int
        deriving (Show)
Run Code Online (Sandbox Code Playgroud)

(实际的机器可能有多个寄存器,程序指针,调用堆栈等等,但现在不要担心.)在上一个问题之后我知道如何使用状态monad实现机器,所以我不必显式传递其内部状态.在这个简化的示例中,导入后实现如下所示Control.Monad.State.Lazy:

addToState :: Int -> State Machine ()
addToState i = do
        (Register x) <- get
        put $ Register (x + i)

getValue :: State Machine Int
getValue = do
        (Register i) <- get
        return i
Run Code Online (Sandbox Code Playgroud)

这让我可以写出类似的东西

program :: State Machine Int
program = do
        addToState 6
        addToState (-4)
        getValue

runProgram = evalState program (Register 0)
Run Code Online (Sandbox Code Playgroud)

这会将6添加到寄存器,然后减去4,然后返回结果.状态monad跟踪机器的内部状态,以便"程序"代码不必明确跟踪它.

在命令式语言的面向对象样式中,这个"程序"代码可能看起来像

def runProgram(machine):
    machine.addToState(6)
    machine.addToState(-4)
    return machine.getValue()
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果我想模拟两台彼此交互的机器,我可能会写

def …
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad lenses haskell-lens

14
推荐指数
2
解决办法
437
查看次数

标签 统计

haskell ×1

haskell-lens ×1

lenses ×1

monads ×1

state-monad ×1