Standard ML

236319 Spring 2024, Prof. Lorenz


Standard ML

modules


structures

A structure is a collection of bindings

structure MyModule = struct
    (*bindings*)
end

These are our modules in SML, or better considered as module implementations.

Somewhat like a namespace in c++;

structures

A module may contain any kind of binding:

structure MyModule = struct
    val answer = 42
    exception Failure of int
    type key = int
    fun foo x = x
end;

modules usage

Outside a module, we may refer to a binding like so:

MyModule.answer;

modules usage

open MyModule;
answer;
  • Used to get direct access to the bindings of a module (kind of like using namespace in C++)
  • Considered bad style

signatures

A signature includes the types of the bindings in a module

signature SIGNAME = sig
    (*types for bindings*)
end

structure ModuleName :> SIGNAME = struct
    (*bindings*)
end

Somewhat like a header file in C++

signatures

signature MATHLIB = sig
    val pi: real
    val deg2rad: real -> real
end;

structure MathLib :> MATHLIB = struct
    val pi = 3.14
    fun deg2rad x = x / 180.0 * pi
end;

signatures

When a structure is matched to a signature, the compiler checks that it satisfies the signature requirements:

signature CONSTANTS = sig
    val pi: real
    val e: real
end;
structure MathConstants :> CONSTANTS = struct
    val pi = 3.14
end; (*ERROR*)
structure MathConstants :> CONSTANTS = struct
    val pi = 3
    val e = 2.71
end; (*ERROR*)

signature matching

structure Foo :> BAR

The compiler checks that:

  • Every type in BAR is provided in Foo as specified
  • Every val binding in BAR is provided in Foo
  • Every exception in BAR is provided in Foo

signature matching

structure Foo :> BAR

Foo may have more bindings than specified by BAR, however they are not accessible from outside the module

functors

A functor is a parameterized module

functor Functor (Module: SIG) =
  struct
    (*bindings*)
  end;

Somewhat like a template in C++

functors

Applying a functor to a module creates a new module:

structure FModule = Functor(Module);

Somewhat like a template instantiation in C++

functors - exapmle

signature ORDERED_TYPE = sig
  type t
  val compare: t * t -> order
end;

structure Int' = struct
  type t = int
  val compare = Int.compare
end;

functors - example

functor SortedList (Elt: ORDERED_TYPE) = struct
  fun add x [] = [x]
    | add x (hd :: tl) = case Elt.compare (x, hd) of
        EQUAL => hd::tl
      | LESS => x :: hd :: tl
      | GREATER => hd :: (add x tl)
  (*more functions*)
end;

functors - example

structure SortedIntList = SortedList(Int');

open SortedIntList;
add 5 (add 6 (add 2 (add 4 (add 3 (add 1 [])))));

functors - example

structure SortedStringList = SortedList(struct
  type t = string
  val compare = String.compare
end);
open SortedStringList;
add "abc" (add "hij" (add "efg" (add "nop" (add "klm" []))));