[   ^ to index...   |   next -->   ]

CSE 341 : 19 April 2001

User-defined datatypes

    type namedInt = (string * int);
    val xBinding:namedInt = ("x", 15);

Type synonyms are simple shorthand for whatever's on the right hand side of the type synonym declaration. More interesting are user-defined data types:

    (* Simple "enumeration" *)
    datatype Colors = Red | Orange | Yellow | Green | Blue | Indigo | Violet;

    (* A type with components *)
    datatype MyNumber = MyInt of int | MyReal of real;

    (* A recursive type *)
    datatype StringTree = 
        Nothing
        | StringTreeNode of string * StringTree * StringTree;

    (* A recursive polymorphic type *)
    datatype 'a Tree =
        NullNode
        | TreeNode of 'a * 'a Tree * 'a Tree;

    (* Instantiating a tree node *)
    val oneTree = TreeNode(4,
                      TreeNode(2, NullNode, NullNode),
                      TreeNode(7, NullNode, NullNode));

Skimming the surface of ML modules

ML has a very powerful, flexible, and expressive module system. We won't have time to cover them fully this quarter, but here's the most basic use of modules:

structure MyStuff =
struct
    datatype MyNum = MyInt of int | MyReal of real;

    val myZero = MyInt(0);

    fun myAdd(MyInt(x),  MyInt(y))  = MyInt(x+y)
      | myAdd(MyInt(x),  MyReal(y)) = MyReal(real(x) + y)
      | myAdd(MyReal(x), MyInt(y))  = MyReal(x + real(y))
      | myAdd(MyReal(x), MyReal(y)) = MyReal(x + y);
end;

The above creates a struct (completely unlike a C struct in form and purpose!), and binds it to a structure name. Now, if any code outside this block wants to access any of the functions or types therein, that code must prefix the structure name:

val seal = MyStuff.MyReal(3.14159);
val bear = MyStuff.MyInt(21);
val theFreakishSealBear = MyStuff.myAdd(seal, bear);

Keunwoo Lee
Last modified: Thu Apr 19 10:52:54 PDT 2001