我正在模拟一个 4 位微处理器。我需要跟踪寄存器、内存和运行输出(还有一个获取执行周期计数器的奖励点)。我已经设法在没有单子的情况下做到了这一点,但是一次明确地传递这么多东西感觉很混乱。此外,函数定义混乱、冗长且难以阅读。
我试图用 monads 做到这一点,但它不适合在一起。我尝试将所有单独的状态组件视为单一类型,但这给我留下了如何创建值的问题。
State Program () -- Represents the state of the processor after a single iteration of the fetch execute cycle
是唯一有意义的类型。但在这一点上,为什么还要打扰呢?我尝试通过将字符串从复合类型中拉出并将其视为值来分解它
State Program' String
效果很好,除了我需要 RUNNING 输出。无论我做什么,我都无法同时抓住字符串和状态。
现在我正在努力解决单子变压器。似乎我必须分离出所有不同级别的状态。但我的头快要爆炸了。
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 计数器呢!
问题:
- 我在正确的轨道上吗?
- 看到我现在正在拔出单子变压器,是否可以停止将“运行输出”视为状态并将其交给 IO 单子?那太棒了,我可以打印它,而不是坚持它。
- 我应该将状态分为多少层?我可以看到两个不同的层,但它们彼此密切相关(内存和寄存器都取决于内存和寄存器的状态)。我应该将它们作为一个单一的状态保持在一起还是将它们分开并堆叠起来?哪种方法会产生最易读的代码?