私は4ビットのマイクロプロセッサをエミュレートしています。私は、レジスタ、メモリ、実行中の出力(フェッチ実行サイクルカウンタを持つためのボーナスポイント)を追跡する必要があります。私はモナドなしでこれを行うことができましたが、それはあまりにも多くのものを明示的に一気に渡しています。また、関数の定義が乱雑で長くて読みにくいです。haskellの異なるレベルの相互作用レベル
私はモナドでこれをしようとしましたが、それだけでは合わないのです。私は別々の州のすべてのコンポーネントを単一のタイプとして扱うことを試みましたが、それは私に価値をどうにかするのかの問題を残しました。
State Program() -- Represents the state of the processor after a single iteration of the fetch execute cycle
これは意味をなさない唯一のタイプです。しかし、その時点でなぜ気になるのでしょうか?私は私の複合型の外に列を引っ張り、私はRUNNING出力を必要としているという事実を除いて、とてもうまくいった価値
State Program' String
としてそれを処理することにより、それを破壊しようとしました。私が何をしたとしても、私は文字列と状態の両方を同時に保持することができませんでした。
私はモナド変圧器に取り組もうとしています。私はすべての異なるレベルの国家を分離しなければならないようです。しかし、私の頭は急激に爆発しています。
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モナドに手を差し伸べることはできますか?それはそれを保持する代わりに、私はそれを印刷することができる素晴らしいです。
- 状態を何層に分ける必要がありますか?私は2つの別個の層を見ることができますが、お互いに密接に依存しています(メモリとレジスタの両方がメモリとレジスタの両方の状態に依存します)。私はそれらを単一の状態としてまとめるか、それらを分けて積み重ねるべきですか?どちらのアプローチが最も読みやすいコードを生成するでしょうか?
「実行出力」は、おそらくWriterモナド(http://monads.haskell.cz/html/writermonad.htmlを参照)を使用して最もよく表現されますか? –