.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.Последнее не будет иметь место с абстрактным типом.