5

私はOcamlを初めて使用し、小さなサンプルアプリケーションを作成しようとしています。ocamlcLinuxUbuntu10.04でバージョン3.11.2を使用しています。2つのファイルをコンパイルしたい:

a.ml
b.ml

ファイルb.mlはからの定義を使用しますa.ml。私が理解している限り、私はocamlc -cコンパイルのみを実行するために使用できます。すべてのファイルが実行可能ファイルにリンクされocamlcたら、最後にもう一度呼び出すことができます。.cmoまた、別のファイルの定義を使用するファイルをコンパイルする場合.cmi、外部定義を見つけるファイルをコンパイラーに指示する必要があります。

だから私の考えは使用することでした:

ocamlc -i -c a.ml > a.mli
ocamlc -c a.mli b.ml
ocamlc -o b a.cmo b.cmo

最初のステップは機能し、ファイルa.mliとを生成しますa.cmoが、2番目のステップを実行すると

File "b.ml", line 1, characters 28-31:
Error: Unbound value foo

ここfooで、はで定義されa.ml、で呼び出される関数ですb.ml

だから私の質問は:各ソースファイルを個別にコンパイルし、コマンドラインでインポートするインターフェイスを指定するにはどうすればよいですか?私はドキュメントを調べていて、理解できる限り、.mli含めるファイルを指定する必要がありますが、その方法がわかりません。

編集

ここにいくつかの詳細があります。ファイルa.mlには定義が含まれています

let foo = 5;;

ファイルb.mlに式が含まれています

print_string (string_of_int foo) ^ "\n";;

実際の例はもっと大きいですが、これらのファイルでは、上記で報告したエラーがすでに発生しています。

編集2

私はファイルを編集b.mlして置き換えましfooたが、これは機能します(この質問にとって重要ではない別のコンパイルエラーがある場合でも、A.foofooが表示されます)。によって提案されている b.mlように、自分のファイルを明示的に書き込む方がクリーンだと思います.mli

4

2 に答える 2

5

unbound valueジェフリーの答えで説明されているように、最初に問題を修正します。これは、使用しているコマンドに関するコメントです。

コンパイルをいくつかのステップで分解することは、何が起こっているのかを理解するための良い方法です。モジュールのa.mli一部の値を非表示にする可能性が最も高い独自のファイルを作成する場合は、このファイルの最初のバージョンを取得して編集するための良い方法です。ただし、触れていない場合は、生成する必要はありません。直接入力することもできます。Aocaml -i -c a.ml > a.mlia.mli

ocamlc -o foo a.ml b.ml

を生成しa.cmob.cmo実行可能fooです。

(これは、を発行することによって取得する、a.cmiのコンパイル済みバージョンであるも生成します。同様に、も生成します)。a.mliocamlc -c a.mlib.cmi

順序が重要であることに注意してください。コマンドラインでa.ml前に指定する必要があります。b.mlこのように、コンパイル時b.mlに、コンパイラはa.mlモジュールを見つけてどこにあるかをすでに認識していますA


さらにいくつかのコメント:

  • あなたは「私が理解している限り」の段落に正しいです。
  • 個別のファイルを実際に含めるのではなく、PythonでのインポートAに似ています。モジュールの値は使用可能ですが、名前はA.foo。です。の内容は、で定義されたモジュールの値にa.mlコピーペーストされておらず、コンパイルされたバージョンにアクセスされています。b.mlAa.mla.cmo
  • でこのモジュールを使用している場合はAb.mlコマンドラインで次のいずれかを前に渡すことができますb.ml
    • a.mli、にコンパイルされますa.cmi
    • a.cmiすでにコンパイルa.mliしている場合a.cmi
    • a.mla.cmoまたは、独自に作成する必要がない場合a.mli、つまりモジュールのデフォルトのインターフェイスがA適している場合は、コンパイルされたバージョン。(このインターフェースは単にのすべての値ですa.ml)。
于 2012-10-07T19:08:11.803 に答える
5

動作していないコードを表示すると、より明確になります。ただし、Kristopher が指摘するように、最も可能性の高い問題は、どのモジュールが含まれているかを指定していないことですfoo。モジュールを明示的に指定できますA.fooopen Aまたは、名前をそのまま使用することもできますfoo

open小さな例では問題ありませんが、大きなプロジェクトでは自由に使いすぎないように注意する必要があります。モジュールで適切な名前を自由に使用できるようにしたいのですが、あまりにも多くのモジュールを開くと、適切な名前が互いに競合する可能性があります。

于 2012-10-07T18:49:35.097 に答える