2012-02-27 5 views
3

Можно создать дубликат:
Two fields of two records have same label in OCamlЭтикетки должны быть уникальными во всем мире?

В OCaml 3.12.0, является необходимым, чтобы любые метки записи имеют глобально уникальные имена?

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 

Я думаю, если запись создана анонимно, единственный путь для компилятора, чтобы узнать, какой тип я имею в виду, это имена записей. Означает ли bar скрыть foo?

ответ

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' также очень удобно в этом контексте, например. можно написать «пусть открыто Foo в f = {a = 3; b = 'a'} '. – alavrik

+0

@AntonLavrik: Спасибо за отзыв о 'open'. Это действительно полезно. – pad