Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to include a module in a .mli file?

Tags:

ocaml

Can I include libraries in an mli file?

For example, say I make the following mli file

include Base
val bluh : int -> int

I get an unbound module Base error.

But, If I change the file to a .ml file, and change the contents to

include Base
module type bluh1 = sig
val bluh : int -> int end

it compiles. So the Base library is clearly around, I just can't use it in an .mli file for some reason.

Thank you!

like image 638
push33n Avatar asked Oct 28 '25 01:10

push33n


1 Answers

I get an unbound module Base error.

This is actually not the error that you are getting. The compiler is actually saying,

Unbound module type Base

Emphasis on module type.

When you define an interface in the mli file you're defining types and signatures not values and module implementations. So you can, but don't do this, include the signature of the module Base using the following syntax,

include module type of Base (* a very bad idea, but works *)

But don't do this. There is absolutely no reason to take the whole Base library (which is huge) and include all its implementation and interface into your own module. In order to use a library, you don't need to do anything in the source code, i.e., you don't need to include or open or otherwise require or import it. Libraries in OCaml, as well as in most compiled languages, are managed on the toolchain (aka compiler) level. So if you need a library you shall instruct your build system to link with it (e.g., add it to the libraries stanza in dune or to BuildDepends in oasis, etc).

As far as I can see, you have already done this. Now if you want to use a function (or a module or any other definition) from the Base module of the base library, you just need to prefix it with Base. e.g.,

let empty = Base.Map.empty (module Base.String)

If you don't want to prefix every name, you can use open Base in the beginning of your module, this will allow you to reference any definition in Base without explicitly prefixing it, e.g.,

(* the recommended way *)
open Base
let empty = Map.empty (module String)

While in general it is not recommended to open a module, some modules are designed to be opened, and try not to pollute your namespace with definitions. The Base module is an example of such a module, especially since it acts like an overhaul of the standard library.

like image 101
ivg Avatar answered Oct 29 '25 16:10

ivg