モナドのインタープリタ
モナドを実行するインタープリタを書かないといけません。必要なのはaicmdを受け取って、次に実行するコマンドと残りのaicmdを返す関数です。OCaml側がその関数を順に呼び出します。
とりあえずの実装なので、動くんだけど効率とかよくないし直したい。継続を返すようにするともっと効率がよくなる気がするし、よく考えたらCoFixpointで実装してもいい気がする。多分。
最初のフェーズはモナドの先頭部分がコマンドになるまで、bindを崩していきます。
hnf_cmd : forall A, cmdex A -> cmdex A. hnf_ai : forall A, aicmd A -> aicmd A.
がそれを行います。match in return withが飛び交う修羅場になっています。
hnf_cmdはコマンドcを受け取ると、cで場合分けして
- c' >>= f の形でない場合はc自身を返す
- c' >>= f の形だったら、再帰的に c' に適用する。その結果の c'' で場合分けして
よく考えると、ExNopは必要ないです。ret ttを使えばいいので。
hnf_aiはほとんど同じですが、arun に対しては hnf_cmd を呼び出します。