2010-01-04 3 views
3

Я пытаюсь определить тип типа:ocaml тип записи и null

тип aaa = NULL | {a: int; b: int} ;;

Но компилятор не позволяет это делать. Я не уверен, почему мы не можем смешивать тип записи с чем-либо еще.

Мне нужно сопоставить значение, если это тип записи или нулевая запись, и я устал от создания фиктивной записи, например {a = -999; b = -999}.

есть ли лучший способ?

ответ

7

«Запись» часть определения должна выполняться отдельным типом. Затем вы можете обернуть это в тип «option», если хотите выразить «None» или «Some value».

type aaa = {a: int; b: int} 
type bbb = aaa option 
7

Первая проблема: в подход Objective Caml вы не можете иметь чистые типы соединений без конструкторов. Рассмотрим следующую загадку:

type test = Null | {a : int ; b: int } 

let value = { a: 0 ; b : 42 } in print_int value.a 

Вторая строка неверна, так как value, относится к типу союза, и, следовательно, может быть Null, который не имеет ни одного члена a. Это приведет к неявному предположению о значении типа объединения, который Objective Caml избегает любой ценой. Это означает, что вам нужен конструктор.

Но даже этого будет достаточно, потому что тогда вы бы анонимный тип записи:

type test = Null | Pair of { a : int ; b : int } 

match Pair { a : 0 ; b : 42 } with 
    | Null -> 0 
    | Pair p -> p.a 

Что бы тип p здесь? Это, безусловно, можно было бы решить, разрешив анонимные типы записей в язык, но это не простое дополнение, так как такие типы, как правило, трудно обрабатывать с помощью подхода унификации типов и требуют большого количества дополнительных конструкций для поддержки (например, < ; ... >, #type и value :> type конструкции для обработки объектов).

Дизайнеры языка выбрали простой путь и потребовали, чтобы все типы записей получили имя. Конечно, если у вас чрезвычайно простая запись, вы можете использовать кортеж:

type test = Null | Pair of int * int 
+0

Блестящий ответ, унификация - это действительно головная боль, я не могу получить всю картину за ней – 0xFF

Смежные вопросы