私は4ビットのマイクロプロセッサをエミュレートしています。レジスタ、メモリ、および実行中の出力を追跡する必要があります (フェッチ実行サイクル カウンターもあるというボーナス ポイント)。私はモナドなしでこれを行うことができましたが、一度に多くのものを明示的に渡すのは面倒です。また、関数定義はごちゃごちゃしていて、長くて読みにくいです。
私はモナドでこれをやろうとしましたが、うまくいきません。個別の状態コンポーネントをすべて 1 つの型として扱ってみましたが、値を何にするかという問題が残りました。
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 モナドにパームオフすることは可能ですか? それを保持する代わりに、印刷するだけでよいのです。
- 状態を何層に分ける必要がありますか? 2 つの異なる層が見えますが、それらは互いに密接に依存しています (メモリとレジスタの両方が、メモリとレジスタの両方の状態に依存しています)。ひとつにまとめておくべきか、バラバラにして積み上げるべきか。最も読みやすいコードを生成するアプローチはどれですか?