P Varga
P Varga

Reputation: 20269

Private values in OCaml module?

Is is possible to have a let binding (whether a function, value etc.) that is private to its module, and not visible from outside?

Let's say we have A.ml:

let exported = 1
let local = 2

I only want exported to be accessible from other modules. B.ml:

let a = A.exported
let error = A.local (* This should error *)

Similar to what let%private does in Reason.

Upvotes: 3

Views: 1602

Answers (3)

glennsl
glennsl

Reputation: 29126

This isn't idiomatic, but for completion's sake:

Since 4.08, when open was extended to accept arbitrary module expressions, it's possible to create private bindings without using module signatures:

open struct
  let local = 2
end

Before this you'd have to give the module a name and then open it, which will expose the module with its contents, although it can of course be given a name that suggests it shouldn't be used.

module Internal = struct
  let local = 2
end

open Internal

Upvotes: 4

glennsl
glennsl

Reputation: 29126

Yes, that's what module signatures and on the file level the .mli file is for.

Briefly explained, add an A.mli, then put the definitions you want to export into it:

val exported : int

Upvotes: 3

octachron
octachron

Reputation: 18912

This is the motivation behind signature and mli files: they allow to hide information to the external world and expose only the relevant part of your API and not implementation details. In your case, it would look like

(* A.ml *)
let exported = 1
let local = 2

and

(* A.mli *)
val exported: int

Then only exported will be visible outside of A.ml.

Upvotes: 6

Related Questions