From Textbook: Code Reuse with Modules
Includes
Def: includes
enables a structure to include all the values defined by another structure, or a signature to include all the names declared by another signature.
Syntax
1 | module type SetExtended = sig |
Encapsulation
1 | module ListSetDupsImpl = struct |
The important change is that ListSetDupsImpl
is not sealed, so its type 'a t
is not abstract. Plus, OCaml compiler can infer it is an implementation of Set
.When we include it in ListSetDupsExtended
, we can therefore exploit the fact that it’s a synonym for 'a list
.
The clients should use ListSetDups
, but when we use List to implement other things, we should use ListSetDupsImpl
instead.
Includes vs. Open
1 | module M = struct |
N
has both an x
and y
, whereas O
has only a y
. The reason is that include M
causes all the definitions of M
to also be included in N
, so the definition of x
from M
is present in N
. But open M
only made those definitions available in the scope of O
, aka. a part of the implementation; it doesn’t actually make them part of the structure, aka. the client cannot see them. So O
does not contain a definition of x
, even though x
is in scope during the evaluation of O
‘s definition of y
.
Functors
Def: a functor is simply a “function” from structures to structures. It is a parametrized module.
Syntax
1 | module F (M : S) = struct |
1 | module ANewModule = F(OldModule) |
Application
Extension
1 | module ExtendSet(S:Set) = struct |
Other than Extension: Testing
1 | module SackTester (S: StackSig) = struct |
The only difference is that because the latter example is about extension, we need to include everything from its parent module.