Lists are a very useful data structure, but not ideal for everything. For many applications, using trees will lead to asymptotically faster programs.
ML allows us to define new data structures including trees with a datatype declaration.
Example: binary trees with values at the internal nodes.
This recursive declaration has two effects:
It declares a brand-new type called intbtree.
It declares two data constructors for that type.
These constructors can be used (like functions) to construct values of the datatype and can be used in patterns to analyze values.
Operations on trees
Suppose using ordered intbtree to represent sets.
Equivalent C code
(Assume NULL pointer corresponds to LEAF.)
Can define a binary tree datatype that carries values of any type:
Here bintree is really a type constructor, rather than a type, because it can be applied to arbitrary types 'a to construct new types 'a bintree.
As expected, we can define polymorphic functions over such types.
Datatypes in General
The tree definitions we've seen are just a special case of a very general mechanism for defining new type (constructors).
In general, a datatype declaration may include:
any number (>0) of data constructors, each with any number ( ) of arguments;
any number ( ) of type variables;
any number (> 0) of mutually-recursive type constructors.
Many familiar types (some of them built-in) are really just special cases of datatypes.
Lists. Built-in lists behave just as though they were defined like this:
Discriminated union types in general.
Booleans. Built-in booleans act just like this:
Enumerated types in general: