Невозможно деконструировать тип продукта после упрощения в OCaml


У меня есть такой простой код в OCaml:

type int_pair = int * int;;
type a = A of int_pair;;
let extract (A x) = x;;

Тестирование моей функции extract, похоже, работает:

# extract (A (1,2));;
- : int_pair = (1, 2)

Я упрощаю его, поэтому ему нужен только один тип:

type a' = A' of int * int;;
let extract' (A' x) = x;;

Но я получаю ошибку:

Error: The constructor A' expects 2 argument(s),
       but is applied here to 1 argument(s)
Самое смешное, что я могу построить значения a'...
# A' (1,2);;
- : a' = A' (1, 2)

...Я просто не могу их деконструировать. Почему?

1 8

1 ответ:

Вам нужно использовать

type a' = A' of (int * int)

Это одно из самых сложных мест в спецификации типа OCaml.

Есть два различных типа, которые слегка отличаются друг от друга:

type one_field = F1 of (int * int)
type two_fields = F2 of int * int

В типе one_field есть одно поле, которое является парой ints. В типе two_fields есть два поля, каждое из которых является int. Хитрость заключается в том, что конструктор выглядит идентично:

# F1 (3, 5);;
- : one_field = F1 (3, 5)
# F2 (3, 5);;
- : two_fields = F2 (3, 5)
Эти два типа различны и фактически представлены в памяти по-разному. (Два поля вариант на самом деле занимает меньше места и немного быстрее в доступе.)