I have an ML file which contains a nested module. For example:
let f n = n + 1
module type M_type = sig
val g : int -> int
val h : int -> int
end
module M : M_type = struct
let g n = n + 2
let h n = n + 3
end
let j n = n |> M.h |> M.g |> f
When writing an MLI for this ML, I wish not to expose M.h
, but I do wish to expose M.g
.
Such as the following:
module type M_type = sig
val g : int -> int
end
module M : M_type
val j : int -> int
The above combination of ML and MLI does not compile.
The idea is that my nested module M
contains some functions that I do wish to expose to other functions in the parent module, but not to a user of the parent module.
Is there a legal way to achieve this? If there is none, what is the best alternative to achieve this kind of narrowing of the signature?
Thanks!
If you look closely at the compiler error:
you will see that the compiler does not complain about the module
M
, but about the module typeM_type
.Indeed, the definition of the two module type does not match:
is not compatible with
There are many ways to fix this problem. One possibility is to not use module type as signature constraint when unneccessary:
Similarly, the mli file can be written as
Another possibility is to only define the constrained module type
with the associated mli file:
It is also possible to define an extended module type
EXT
for the.ml
file: