сделать конструкторы вариантов публичными в .mli - PullRequest
0 голосов
/ 30 января 2019

Рассмотрим something.ml:

type some_type =
  | This
  | That

Затем я могу реализовать main.ml следующим образом:

let x = Something.This

Я хочу создать something.mli и сохранить те же функции вmain.ml.Моей первой попыткой было написать something.mli как:

type some_type

Я думал, что это сделает конструкторы вариантов общедоступными, но этого не произошло, и теперь main.ml не компилируется.Есть ли способ выставить конструкторы вариантов в .mli?

Ответы [ 2 ]

0 голосов
/ 31 января 2019

.mli-файлы определяют интерфейс для модуля самостоятельно, а .ml-файл вообще не используется при их компиляции.На самом деле вы можете иметь файл .mli для пакета, состоящего из нескольких файлов .ml.Никогда не извлекайте что-либо волшебным образом из файла .ml в интерфейс.

Теперь, как и в файле .ml, существует три способа указать тип в файле .ml:

1) Как абстрактный тип.Ничего не раскрывается типа:

# type some_type;;
type some_type
# let v = This;;   
Error: Unbound constructor This
# let to_int = function This -> 1 | That -> 2;;
Error: Unbound constructor This

Это скрывает детали типа извне, позволяя модулю изменить тип по желанию позже, не нарушая никакого исходного кода.Он также используется для фантомных типов, которые не имеют значений или внешних значений (см. Взаимодействие с C в руководстве), которые не являются типами ocaml.

2) Как открытый тип.Структура типа представлена ​​и значения могут быть созданы:

# type some_type = This | That;;
type some_type = This | That
# let v = This;;
val v : some_type = This
# let to_int = function This -> 1 | That -> 2;;
val to_int : some_type -> int = <fun>

Это противоположно первому случаю.Все обнародовано.

Но есть и третий вариант:

3) Как частный тип.Структура типа представлена, но значения не могут быть созданы:

# type some_type = private This | That;;
type some_type = private This | That
# let v = This;;
Error: Cannot create values of the private type some_type
# let to_int = function This -> 1 | That -> 2;;
val to_int : some_type -> int = <fun>

Это в некоторой степени от 1 до 2. Вариант использования для этого - когда вам нужно контролировать построение значений.Например, рассмотрим тип, который содержит маленькие целые числа меньше 100. Вы должны написать:

# let make x =
      if x < 0 || x >= 100
          then raise (Invalid_argument "Out of range")
          else x;;
val make : int -> int = <fun>

Затем вы запишите файл .mli как:

type t = private int;;
val make : int -> t;;

Это гарантирует, что значения типаt можно построить только с помощью функции make.Все, что ожидает тип t, примет только значение типа t, созданное make.С другой стороны, все, что ожидает тип int, также примет значение типа t.Последнее не будет иметь место с абстрактным типом.

0 голосов
/ 30 января 2019

Файлthing.mli предоставляет интерфейс для файла some.ml.Поэтому все, что вы хотите видеть в интерфейсе, должно быть определено в нечто .mli.

Поскольку вы хотите, чтобы This и That были видимыми, они должны быть определены в что-то.mli.

Для вашего небольшого примера что-то.m.mli будет содержать именно то, что вы показываете для чего-то .ml выше:

type some_type = This | That

В более реалистичном примере, конечно, интерфейс будет содержать гораздо меньше, чемреализация.В частности, он просто имеет типы открытых функций, а не код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...