Enum type declarations define a new type by enumeration:
Color = RED | GREEN | BLUE;
Variables of type Color may take on only the values RED, GREEN or BLUE.
Every such declaration without exception creates a new type, not equal to any existing type, even if it is lexically identical to another such declaration.
The value keywords defined by such a declaration may have associated values:
Binary_Tree = LEAF | NODE { key: Float, left_kid: Binary_Tree, right_kid: Binary_Tree } ;
Here internal nodes on the tree carry a record containing a float key and two child pointers; leaf nodes carry no value.
An instance of such a tree may be created by an expression such as
my_tree = NODE { key => 2.0, left_kid => NODE { key => 1.0, left_kid => LEAF, right_kid => LEAF }, right_kid => NODE { key => 3.0, left_kid => LEAF, right_kid => LEAF } };
Here NODE functions to construct records on the heap; consequently it is termed a constructor. By extension all such tags declared by an enum are called constructors, even those like RED, GREEN, BLUE and LEAF which have no associated types and thus construct nothing much of interest on the heap.
Recursive sumtypes such as Binary_Tree are usually processed via recursive functions, using case expressions to handle the various alternatives. Here is a little recursive function to print out such binary trees:
linux$ cat my-script #!/usr/bin/mythryl Binary_Tree = LEAF | NODE { key: Float, left_kid: Binary_Tree, right_kid: Binary_Tree } ; my_tree = NODE { key => 2.0, left_kid => NODE { key => 1.0, left_kid => LEAF, right_kid => LEAF }, right_kid => NODE { key => 3.0, left_kid => LEAF, right_kid => LEAF } }; fun print_tree LEAF => (); print_tree (NODE { key, left_kid, right_kid }) => { print "("; print_tree left_kid; printf "%2.1f" key; print_tree right_kid; print ")"; }; end; print_tree my_tree; print "\n"; linux$ ./my-script ((1.0)2.0(3.0))