Включить файл подписи (.mli) в библиотеку

У меня есть библиотека, в которой общие типы данных определены в модуле только для подписи (копирование этой подписи в реализацию не имеет смысла, поскольку она не содержит никаких функций):

(* b.mli *)
type bar = A of int | B of float

(* a.ml: *)
let foo = function B.A i -> B.A (i+1)
                 | B.B f -> B.B (f +. 1.)

(* c.mllib *)
A
B

В приведенной выше настройке ocamlbuild не может создать библиотеку с довольно неожиданной ошибкой:

choeger@daishi /tmp/test % ocamlbuild c.cmxa
Solver failed:
  Ocamlbuild cannot find or build c.ml.  A file with such a name would usually be a source file.  I suspect you have given a wrong target name to Ocamlbuild.

Я могу построить без указания B внутри файла mllib, но тогда панель типов становится абстрактной (что не предназначено). Есть ли способ включить подпись с помощью ocamlbuild?


person choeger    schedule 08.01.2015    source источник


Ответы (1)


Вы не можете упаковать B модуль в библиотеку, потому что он не существует. У вас есть только скомпилированный интерфейс, а не скомпилированный модуль, т.е. модуль компиляции. Назначение cmxa состоит в том, чтобы быть контейнером для скомпилированного кода, поскольку ваш интерфейс B не содержит никакого кода, ничего нельзя поместить в библиотеку. Это означает, что вам вообще не нужно помещать ссылку на модуль B в файл mllib.

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

type bar = A of int | B of float with sexp

Но если вы все еще хотите иметь mli без ml, я бы посоветовал вам использовать oasis. У него есть функция под названием pure_interface, которая позволяет создавать такие библиотеки.

person ivg    schedule 08.01.2015
comment
Это имеет больше смысла. Вероятно, не следует привыкать к использованию пакета, поскольку он не поддерживает псевдонимы модулей. - person nlucaroni; 08.01.2015