In OCaml, referring to constructors defined in other modules can be somewhat awkward. Suppose we have a module like the following.
module Example = struct
type t = Foo | Bar | Baz
end
To write a function that pattern matches on values of type Example.t
we could
directly refer to the variants as follows.
let f e =
match e with
| Example.Foo -> ...
| Example.Bar -> ...
| Example.Baz -> ...
That is pretty verbose. We could alleviate the problem by opening Example
.
open Example
let f e = match e with
| Foo -> ...
| Bar -> ...
| Baz -> ...
That is nicer to look at, but the open
potentially brings a lot of things into
scope (and not just for f
, but for the rest of the file). Using open
is
generally bad style because it makes it hard for a reader to connect definitions
with uses. The open
would be less problematic if we could reduce its scope. We
can do that by using a local module.
let f e =
let module M = struct
open Example
let res =
match e with
| Foo -> ...
| Bar -> ...
| Baz -> ...
end in
M.res
That’s pretty verbose too. The approach we’ve settled on at Jane Street is to
use let module
to rebind the module to a short name, thereby making the code
concise and avoiding the open
entirely.
let f e =
let module E = Example in
match e with
| E.Foo -> ...
| E.Bar -> ...
| E.Baz -> ...