【发布时间】:2012-02-23 23:35:46
【问题描述】:
我正在模拟一个 4 位微处理器。我需要跟踪寄存器、内存和运行输出(还有一个获取执行周期计数器的奖励点)。我已经设法在没有单子的情况下做到了这一点,但是一次明确地传递这么多东西感觉很混乱。此外,函数定义混乱、冗长且难以阅读。
我试过用 monad 来做这件事,但它就是不适合。我尝试将所有单独的状态组件视为单一类型,但这给我留下了如何制作价值的问题。
State Program () -- Represents the state of the processor after a single iteration of the fetch execute cycle
是唯一有意义的类型。但在这一点上,为什么还要打扰呢?我尝试通过将字符串从复合类型中拉出并将其视为值来分解它
State Program' String
效果很好,除了我需要 RUNNING 输出。无论我做什么,我都无法同时保持字符串和状态。
现在我正在努力解决 monad 转换器。似乎我必须分离出所有不同级别的状态。但是我的脑袋快爆炸了。
StateT Registers (StateT Memory (State Output)) a =
StateT (registers -> (StateT Memory (State Output)) (a,registers))
StateT Registers (StateT Memory (State Output)) a =
StateT (registers -> (Memory -> (Output -> (((a,Registers),Memory),Output))))
我还没把FEcycle计数器放进去!
问题:
- 我在正确的轨道上吗?
- 看到我现在正在拔出 monad 转换器,是否可以停止将“运行输出”视为状态,而只是将其交给 IO monad?那太棒了,我可以打印它而不是坚持它。
- 我应该将状态分为多少层?我可以看到两个不同的层,但它们彼此密切相关(内存和寄存器都取决于内存和寄存器的状态)。我应该将它们作为一个单一的状态保持在一起还是将它们分开并堆叠起来?哪种方法会产生最易读的代码?
【问题讨论】:
-
也许“正在运行的输出”可能最好使用 Writer monad 来表示(参见 monads.haskell.cz/html/writermonad.html)?
标签: haskell state monads monad-transformers state-monad