I'd like to extend a module but I need access to its private components. Here's an example:
nat.mli:
type t
val zero : t
val succ : t -> t
nat.ml:
type t = int
let zero = 0
let succ x = x + 1
I'd like to define a new module Ext_nat
that defines a double
function. I was trying to do something like this.
ext_nat.mli:
include (module type of Nat)
val double : t -> t
ext_nat.ml:
include Nat
let double x = 2 * x
It's not working as I don't have access to the representation of x
in the last line.
Now that I'm thinking about this, it may not be such a good idea anyway because this would break the encapsulation of nat
. So what is the best way to do this? I could define a new module nat_public
where type t = int
in the signature, and define nat
and ext_nat
with a private type t
. What do you think?
You need to use
with type
statement. It is possible to write the code below in many different ways, but the idea is always the same.The problem is that as far as I remember it's impossible to achieve this behavior with your file structure: you define your module implicitly with signature in .mli file and structure itself in .ml, so you don't have enough control over you module, that's why I suggest you to reorganize your code a little bit (if it's not a problem).