There is a way to define a namespace in SML: define an "structure" that creates a module.
Example:
structure MyMath =
struct
val pi = 3.141529
fun double(x) =
x + x
endTo access the bindings, you need to prepend the namespace:
MyMath.double(2)
=> 4It is possible to provide a kind of "interface" to our modules, saying that only some vals and function bindings will be available to the external world.
signature MY_SIGNATURE
sig
val add : int * int -> int
endEvery module that implements MY_SIGNATURE will only have the things defined in the signature as public. This way, it is easy to encapsulate things. It also enables to make "types" abstract.
Eg.:
structure MyStructure :> MY_SIGNATURE
struct
fun add(a, b) =
a + b
val pi = 3.1415 (* This will not be available to the outside world *)
endEven if a module shares the same signature, it is not equivalent in types. Every signature defines its own types. You can't mix implementations that are equivalent, but does not share the same signature. This is because signature a has types that are diffent than signature b.