datatype color = red | blue | green;This will declare the type color and three constuctors: red, blue, green. These constructors can now be used within patterns. For example,
fun warmth red = 1 | warmth blue = 2 | warmth green = 0;is a function that maps colors to integers.
For another example, consider the data type of numbers, which is composed of either integers or real numbers.
datatype number = r of real | i of int;Here there are two new constructors,
fun addnumbs(nil) = 0.0 | addnumbs(i x :: k) = real(x) + addnumbs(k) | addnumbs(r x :: k) = x + addnumbs(k);Entering the following line to the interpreter
val x = addnumbs((i 1 :: r 5.4 :: i 9 :: nil));returns
val x = 15.4 : realIt is possible to also introduce polymorphic user datatypes, similar to lists. Consider the following declaration of binary trees that contains the empty tree and non-empty trees with nodes of type 'a:
datatype 'a btree = emptybt | consbt of 'a * 'a btree * 'a btree;Two new constructors are introduced, namely,
consbt(1, consbt(2,emptybt,emptybt), consbt(3,emptybt,emptybt))denotes the tree
1 / \ / \ 2 3while the expression
consbt(1, consbt(2, emptybt,emptybt), consbt(3, consbt(4,emptybt,emptybt), emptybt))denotes the tree
1 / \ / \ 2 3 / / 4We can now write functions that can compute on binary trees. Forinstance, the following function height computes the height of a tree.
fun max(x,y) = if x < y then y else x; fun height(emptybt) = 0 | height(consbt(x,left,right)) = 1 + max(height(left), height(right));The following function will add up the labels in the binary tree. Its type is int btree -> int.
fun sum_labels(emptybt) = 0 | sum_labels(consbt(x,left,right)) = sum_labels(left) + x + sum_labels(right);
The following function takes a binary tree of integers and returns the binary tree with all the labels in it doubled.
fun double(emptybt) = emptybt | double(consbt(x,left,right)) = consbt(2 * x, double(left), double(right));All of the code in the above note is collected below. If you save the lines below into a file, say lnotes.sml, then type
- use "lnotes.sml";into the SML runtime system, that code will be loaded.
(* EXAMPLES OF DEFINITIONS AND USE OF DATATYPES *) datatype color = red | blue | green; fun warmth red = 1 | warmth blue = 2 | warmth green = 0; datatype number = r of real | i of int; fun addnumbs(nil) = 0.0 | addnumbs(i x :: k) = real(x) + addnumbs(k) | addnumbs(r x :: k) = x + addnumbs(k); val x = addnumbs((i 1 :: r 5.4 :: i 9 :: nil)); datatype 'a btree = emptybt | consbt of 'a * 'a btree * 'a btree; val one = consbt(1, consbt(2,emptybt,emptybt), consbt(3,emptybt,emptybt)); val two = consbt(1, consbt(2,emptybt,emptybt), consbt(3, consbt(4,emptybt,emptybt), emptybt)); fun max(x,y) = if x < y then y else x; fun height(emptybt) = 0 | height(consbt(x,left,right)) = 1 + max(height(left), height(right)); fun sum_labels(emptybt) = 0 | sum_labels(consbt(x,left,right)) = sum_labels(left) + x + sum_labels(right); fun double(emptybt) = emptybt | double(consbt(x,left,right)) = consbt(2 * x, double(left), double(right));