質問

私は実験言語のインタプリタを書いています。言語の主要な構成要素のうちの 3 つは、定義、ステートメント、および式です。定義にはステートメントと式を含めることができ、ステートメントには定義と式を含めることができ、1 種類の式にはステートメントを含めることができます。これらすべてを共用体型を使用して表現しているので、パターン マッチングを簡単に使用できます。理想的には、これらのコードを別のファイルに置きたいのですが、OMake は循環依存関係の問題について不満を抱いています。私の知る限り、モジュール間での循環型定義は許可されていません。

これを解決するために私が知っている唯一の方法は、3 つのタイプすべてを一度に定義することです。

type defn = ...
and stmt = ...
and expr = ...

これには、型のすべてのコードが同じファイル内にある必要があるようです。これを回避する方法はありますか?コード内の循環定義をどのように処理しますか?

役に立ちましたか?

解決

再帰的定義は同じファイル内に存在する必要があります。定義、ステートメント、および式を別個のモジュールに分割したい場合は、次を使用して行うことができます。 再帰的モジュール, ただし、同じファイル内に存在する必要があります。ファイル間の依存関係を DAG 化することは、OCaml の問題点の 1 つです。

他のヒント

これは、参照する型をパラメータ化することで簡単に解決できます。

type ('stmt, 'expr) defn = ...
type ('defn, 'expr) stmt = ...
type ('defn, 'stmt) expr = ...

このテクニックは「再帰的な結び目を解く」(ゴーディアンの結び目にちなんで)と呼ばれており、次の文献で説明されています。 OCamlジャーナル 記事。

乾杯、ジョン・ハロップ。

よく使用されるもう 1 つの解決策は、インターフェイス内の型を抽象化することです。インターフェイス内の型は抽象的なため、これらのインターフェイスは再帰的に依存しません。実装では型を指定できますが、実装はインターフェイスのみに依存するため、再帰的でもありません。

唯一の問題は、このソリューションでは、実装の外でこれらの型のパターン マッチングができなくなることです。

個人的には、好みの問題かもしれませんが、プログラムのすべてのタイプを 1 つのモジュールで定義するのが好きです (プログラムの読みやすさに役立つと思います)。したがって、OCaml のこの制限は私にとって実際には問題ではありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top