Yao Lirong's Blog

Modules

2020/02/11

From Textbook: OCaml Modules


Structures

Semantics

The first letter of a module’s name should be capitalized.

1
2
3
module ModuleName = struct 
(* definitions *)
end

You can access the variables / methods in a module by Module.method

1
2
let x = ModuleName.empty;;
x.peek;;

Signatures

Semantics

Signature is a collections of declarations; not evaluated, just type checked.

1
2
3
4
5
6
7
8
9
10
11
12
module type ModuleTypeName = sig 
(* declarations *)
end

module type Stack = sig
type 'a stack
val empty : 'a stack
val is_empty : 'a stack -> bool
val push : 'a -> 'a stack -> 'a stack
val peek : 'a stack -> 'a
val pop : 'a stack -> 'a stack
end

A structure matches a signature if the structure provides definitions for all the names specified in the signature (and possibly more), and these definitions meet the type requirements given in the signature.

If you don’t seal X, as long as the fields in module correspond with those in signature, these two match. when we seal X, we a create a linkage between module with the signature but we don’t have to do that. It’s safer if you explicitly want X to be a type of X, but we add an extra layer of abstraction to X.

Abstraction

You can also specify that this module as a type of some signature by providing a module type annotation  : Stack. After adding this, everything inside that module will be come abstract and hidden from view.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module type Arith = sig
type t
val zero : t
val one : t
val (+) : t -> t -> t
val ( * ) : t -> t -> t
val (~-) : t -> t
end

module Ints : Arith = struct
type t = int
let zero = 0
let one = 1
let (+) = Stdlib.(+)
let ( * ) = Stdlib.( * )
let (~-) = Stdlib.(~-)
end

Outside of the module Ints, the expression Ints.(one + one) is perfectly fine, but Ints.(1 + 1) is not, because t is abstract: outside the module no one is permitted to know that t = int. In fact, the toplevel can’t even give us good output about what the sum of one and one is!

1
2
# Ints.(one + one);;
- : Ints.t = <abstr>

Sharing Constraint

OCaml lets you write sharing constraints that refine a signature by specifying equations that must hold on the abstract types in that signature. If T is a module type containing an abstract type t, then T with type t = int is a new module type that is the same as T, except that t is known to be int. For example, we could write:

1
2
3
module Ints : (Arith with type t = int) = struct
(* all of Ints as before *)
end

Now both Ints.(one + one) and Ints.(1 + 1) are legal.

Modules and the Top Level

Well, apparently you cannot remember everything about how to import a library into OCaml and you don’t have to. So just refer to this site

CATALOG
  1. 1. Structures
    1. 1.1. Semantics
  2. 2. Signatures
    1. 2.1. Semantics
    2. 2.2. Abstraction
    3. 2.3. Sharing Constraint
    4. 2.4. Modules and the Top Level