Skip to content

Instantly share code, notes, and snippets.

@philss
Last active December 29, 2016 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philss/9f7e447e62c0f46e1b33a9559bbf4878 to your computer and use it in GitHub Desktop.
Save philss/9f7e447e62c0f46e1b33a9559bbf4878 to your computer and use it in GitHub Desktop.

SML Module System

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
end

To access the bindings, you need to prepend the namespace:

MyMath.double(2)
=> 4

Signatures

It 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
end

Every 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 *)
end

Same signature, different types

Even 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment