**Trees**

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`.)

**Polymorphic trees**

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:

Option type.

Tue May 6 18:23:22 PDT 1997