Module

In Ocaml all functions require one argument.

If you create a module such as this with say_hi receiving no arguments, it executes when the module is loaded in utop.

1let say_hi = Printf.printf "hi\n"
2
3let say_something s = Printf.printf "%s\n" s
4
5let say_unit () = Printf.printf "unit\n"
1val say_hi : unit 
2val say_something : string -> unit 
3val say_unit : unit -> unit 

Create the module cmo file, mod.cmo.

ocamlc -I mod.ml mod.mli
ocamlc -c mod.ml mod.mli

Open utop and load the cmo file.

Loading the module you can see the function say_hi produce their output immediately. Running the command Mod.say_hi does not produce output. It simply outputs unit.

Running Mod.say_something properly takes in the single argument and prints to the screen.

Mod.say_unit also prints to the screen after receiving an unit, (), as input.

utop # #load "mod.cmo";;
hi

utop # Mod.say_hi;;
- : unit = ()

utop # Mod.say_something "some thing";;
some thing
- : unit = ()

utop # Mod.say_unit ();;
unit
- : unit = ()

Now check the type of say_hi vs say_unit.

utop # #typeof "Mod.say_hi";;
val ( Mod.say_hi ) : unit

utop # #typeof "Mod.say_unit";;
val ( Mod.say_unit ) : unit -> unit

The value of Mod.say_hi is unit, and the value of Mod.say_unit is a function unit -> unit

So the print function is no longer attached to say_hi, only the end value, unit.

Compare the type result of Mod.say_hi to a variable.

utop # let x = ();;
val x : unit = ()

utop # #typeof "x";;
val x : unit

off example

if lib/sam_account_name contains a library needed by user.ml in the root directory…

cd lib/sam_account_name

rm *.cmo *.cmi *.cma

# create cmi
ocamlc -I sam_account_name.ml sam_account_name.mli
# create cmo
ocamlc -c sam_account_name.ml sam_account_name.mli
# create cma
ocamlc -a -o sam_account_name.cma sam_account_name.cmo

ls
# dune  sam_account_name.cma  sam_account_name.cmi  sam_account_name.cmo  sam_account_name.ml  sam_account_name.mli

cd ../..

rm *.cmo *.cmi *.cma

# create cmi
ocamlc -I user.ml user.mli lib/sam_account_name/sam_account_name.cma
# create cmo
ocamlc -I lib/sam_account_name/ -c user.ml user.mli 

in utop..

#load "lib/sam_account_name/sam_account_name.cmo";;
#load "user.cmo";;

dealing with libraries

├── bin ├── lib │   ├── dune │   └── sam_account_name │   ├── dune │   ├── sam_account_name.ml │   └── sam_account_name.mli ├── mod.ml ├── mod.mli ├── test │   ├── dune │   └── test_user.ml ├── user.ml ├── user.mli └── user.opam

If we have a lib folder and we want to use the library we compile from it in utop to test our user module…

Compile the sam_account_name module into a .cma file

cd lib/sam_account_name
rm *.cam *.cmo *.cmi
ocamlc -I sam_account_name.ml sam_account_name.mli
ocamlc -c -I ~/.opam/core_ocaml_5_2_2/lib/re/ -I ~/.opam/core_ocaml_5_2_2/lib/core/ sam_account_name.ml sam_account_name.mli 
ocamlc -a -o sam_account_name.cma sam_account_name.cmo

Then compile the user module to create a .cmo

cd ../..
rm *.cam *.cmo *.cmi
ocamlc -I  user.ml user.mli
ocamlc -c -I lib/sam_account_name/ user.ml user.mli 

Open utop, require the ocaml libraries and your module .cmo files.

#require "re";;
#require "core";;

#load "lib/sam_account_name/sam_account_name.cmo";;
#load "user.cmo";;