2

次のように2つのレコードタイプを定義しました。

(* in module A*)
type reg = {name: string; mutable value: Big_int.big_int}
type exp = Reg of reg | Other

(* in module B*)
type abstr = Top | Bot | Elt of int
type register = {name: string; mutable value: abstr}

モジュールBには、私が呼び出すリストがあり、lそれにexpパターンマッチングを実行しています。だから私はこのようなものを持っています:

 List.fold_left (fun l elt ->
     let str =
        match elt with
           | A.Reg r -> r.name
           | _ -> failwith "exception" in
      l@[{name = str; value = Bot}]) [] l

しかし、次のエラーが発生します。式のタイプはA.regですが、タイプregisterが予期されていました。モジュールAの定義がモジュールBの定義によって隠されているようです。「はい」の場合、なぜこのようになっているのですか?誰かが説明できますか?

4

2 に答える 2

5

モジュールのレコードフィールド名を使用するには、次のように入力する必要があります。

value.Module.field

あなたの場合は次のようになります。

r.A.name

A.Regキム・ドクワンも正しいと思いますA.reg

「なぜこのようになっているのか」に対する答え:(素晴らしくて素晴らしい)型推論を取得するためのトラッドは、コンパイラーがオーバーロードされた名前の意味を型から推測できないことです。推論は逆になります(本質的に)。nameしたがって、タイプに基づいて名前が付けられた2つのフィールドを区別することはできません。どちらを意味するかを、明示的に指定する必要があります。同様の制限は、整数と浮動小数点の算術演算子の違いにも現れます。

于 2012-08-06T15:02:13.247 に答える
5

レコードはOCamlでフィールド名を共有できません。レコードタイプのフィールドのフルネームはとexpです。他の名前付き要素と同様に、モジュールA内では、プレフィックスを省略できます。ただし、別のモジュールでは、完全修飾名を使用する必要があります(開いていない場合)。言い換えれば、あなたのエラーを解決するために書いてください。A.nameA.valueA.Ar.A.name

于 2012-08-06T15:07:34.180 に答える