2012-02-27 16 views
3

可能性の重複:OCamlの3.12.0で
Two fields of two records have same label in OCamlレコードラベルはグローバルに一意である必要がありますか?

、それは、レコードのいずれかのラベルがグローバルにユニークな名前を持っている必要がありますか?

type foo = { a : int; b : char; } 
# type bar = {a : int; b : string};; 
type bar = { a : int; b : string; } 
# {a=3; b='a'};; 
    {a=3; b='a'};; 
Error: This expression has type char but an expression was expected of type 
     string 

私はレコードが匿名で作成された場合、コンパイラのための唯一の方法はレコード名である私が参照してるタイプを知っていると思います。 barfooと表示されていますか?

答えて

7

いいえ、レコードラベルはグローバルに一意である必要はありません。しかし、モジュールレベルで一意でなければなりません。

barを宣言しても、fooは非表示になりません。したがって、bフィールドを参照すると、型推論が壊れます。

あなたは簡単にサブモジュールを作成し、同じラベルを持つレコードを区別するためにモジュール名を使用することができます。私は一度だけモジュール名を使用するのに十分であることを知らなかった

module Foo = struct 
    type foo = {a: int; b: char} 
end 

module Bar = struct 
    type bar = {a: int; b: string} 
end 

let f = {Foo.a = 3; b = 'a'} (* Note that we only need to use module name once *) 
let b = {Bar.a = 3; b = "a"} 
+1

、ありがとう!興味のある人のために、私はcamlp4ベースの[構文の拡張子](https://github.com/alavrik/piqi/tree/master/piqi-camlp4)を書いて少しきれいにしました。基本的には、次のように書くことができます: 'Foo#{a = 3; b = 'a'} '。違いは、すべてのネストされたFooでも機能するということです。 – alavrik

+1

「let open ... in」は、この文脈でも非常に便利です。 '' let foo'を 'f = {a = 3; b = 'a'} '。 – alavrik

+0

@AntonLavrik:「オープン」についてのヒントをありがとう。本当に役に立ちます。 – pad

関連する問題