Greg Nisbet
Greg Nisbet

Reputation: 6994

How to get a module alias local to mli file

Is it possible to alias a module in an mli without creating a "new module that must be implemented". This example is pretty contrived, but, for instance, suppose I have the following source file int_wrapper.ml.

type t = Int64.t

let zero = Int64.of_string "0"

And I want to define an interface file for it, but Int64.t is pretty long so I want to abbreviate it.

module I = Int64

val zero : int -> I.t

When attempting to compile the module, I (predictably) get the following error

ocamlbuild int_wrapper.cmo
+ ~/.opam/4.03.0/bin/ocamlc.opt -c -o int_wrapper.cmo int_wrapper.ml
File "int_wrapper.ml", line 1:
Error: The implementation int_wrapper.ml
   does not match the interface int_wrapper.cmi:
   The module `I' is required but not provided
Command exited with code 2.
Compilation unsuccessful after building 4 targets (0 cached) in 00:00:00.
Exit 10

and that's because module I = Int64 is not an alias. I'm actually defining a new module that-just-happens-to-be-identical to Int64 and since that module is in a signature, I'm required to provide an implementation in the source file. Is there a way to get a true alias inside an interface file?

Upvotes: 3

Views: 733

Answers (3)

Kevin Ji
Kevin Ji

Reputation: 10489

As of OCaml 4.08 (see the release notes) this is now possible via local substitution declarations:

module I := Int64

Upvotes: 8

Reimer Behrends
Reimer Behrends

Reputation: 8720

Module aliases need to be present in both the .ml and .mli file, as they're being exported. You can work around it by putting them in a separate file that you use open on, e.g.:

==> abbrevs.ml <==
module I = Int64

==> int_wrapper.ml <==
type t = Int64.t

let zero = Int64.of_string "0"

==> int_wrapper.mli <==
open Abbrevs
val zero : I.t

Upvotes: 3

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66793

There's no way to include a module synonym for local use in an .mli file (as far as I can tell by looking through the OCaml syntax definitions).

If you are willing to define I both in the .ml file and the .mli file, then the .ml file will provide the proper interface.

$ cat a.ml
module I = Int64
type t = I.t
let zero = I.of_string "0"
$ cat a.mli
module I = Int64
type t = I.t
val zero : I.t
$ ocamlc -c a.mli a.ml

Upvotes: 2

Related Questions