1

I have a library were the common datatypes are defined in a signature-only module (copying that signature to an implementation does not make sense, since it does not contain any functionality):

(* 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

In the setup above, ocamlbuild fails to create the library with a rather surprising error:

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.

I can build without specifying B inside the mllib file, but then the type bar becomes abstract (which is not intended). Is there any way to include the signature using ocamlbuild?

choeger
  • 3,562
  • 20
  • 33

1 Answers1

2

You can't pack B module into the library because it doesn't exist. You have only compiled interface, but not a compiled module, i.e., a compilation unit. The purpose of the cmxa is to be a container for a compiled code, since your B interface doesn't contain any code nothing can be put into the library. That means, that you do not need at all to put the reference to the module B into the mllib file.

A more common approach is to put types and interfaces into the ml file without a mli one. I think that this approach is better in comparison to mli only approach, because it allows one to use type-driven code generators, for example, with mli only approach you can't do the following:

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

But, if you still want to have a mli without an ml then I would suggest you to use oasis. It has a feature called pure_interface, that allows you to build such libraries.

ivg
  • 34,431
  • 2
  • 35
  • 63
  • That makes more sense. One probably shouldn't get used to using pack since it doesn't support module alias. – nlucaroni Jan 08 '15 at 15:01