In OCaml, every piece of code is wrapped into a module. Optionally, a module itself can be a submodule of another module, pretty much like directories in a file system-but we don't do this very often.
When you write a program let's say using two files
bmodule.ml, each of these files automatically defines a module named
Amodule and a module named
Bmodule that provide whatever you put into the files.
Here is the code that we have in our file
let hello () = print_endline "Hello"
And here is what we have in
Usually files are compiled one by one, let's do it:
ocamlopt -c amodule.ml ocamlopt -c bmodule.ml ocamlopt -o hello amodule.cmx bmodule.cmx
Now we have a wonderful executable that prints "Hello". As you can see, if you want to access anything from a given module, use the name of the module (always starting with a capital) followed by a dot and the thing that you want to use. It may be a value, a type constructor, or anything else that a given module can provide.
Libraries, starting with the standard library, provide collections of modules. for example,
List.iter designates the
iter function from the
OK, if you are using a given module heavily, you may want to make its contents directly accessible. For this, we use the
open directive. In our example,
bmodule.ml could have been written:
open Amodule;; hello ();;
As a side note, people tend to avoid the ugly ";;", so it more common to write it like:
open Amodule let _ = hello ()
open or not is a matter of personal taste. Some modules provide names that are used in many other modules. This is the case of the
List module for instance. Usually we don't do
open List. Other modules like
Printf provide names that are normally not subject to conflicts, such as
printf. In order to avoid writing
Printf.printf all over the place, it often makes sense to place one
open Printf at the beginning of the file.
There is a short example illustrating what we just mentioned:
open Printf let my_data = [ "a"; "beautiful"; "day" ] let _ = List.iter (fun s -> printf "%s\n" s) my_data