You will find the book Elements
of ML Programming (ML97 Edition) useful. This book will beon
reserve at the S&E Library, and important sections will also be available
online as UCSD e-reserves. It is easy to buy on the web.
Rather more precisely, we can say that a list is either the empty list, or a pair consisting of a "first" element which is an integer and a "second" element which is itself a list of integers. Formally let's write
Here + means tagged union and * means tuple as before. Here are some examples of values of the type integerlist:integerlist = nil + (integer * integerlist)
The last three examples are all special cases of the fact that <13,x> is an integerlist for any x such that x is an integerlist.nil
<13, nil>
<13, <14, nil>>
<13, <4, <8, <16, nil>>>>
datatype intlist = nil | cons of int * intlist;
Remember that you have to choose a tag value for each type being unioned: we choose nil and cons which is short for "construct". So in ML we could write for example
val doubles = cons (2,
cons (4, cons (8, cons (16, nil))));
For examples of ML functions using lists see the sections from the book
Elements
of ML Programming (ML97 Edition) that are available online as
UCSD e-reserves.
Consider for example typical arithmetic expressions, including constants. We can represent the set of all these expressions as a recursive type, and therefore as an ML datatype:
With the data structure defined above, it is easy to write a recursive function that evaluates expressions:datatype expression =
Constant of int |
Plus of expression * expression |
Minus of expression * expression |
Times of expression * expression;
Notice how this function follows the structure of the expression datatype exactly.fun eval (Constant n) = n
| eval (Plus (exp1,exp2) ) = (eval exp1) + (eval exp2)
| eval (Minus (exp1,exp2) ) = (eval exp1) - (eval exp2)
| eval (Times (exp1,exp2) ) = (eval exp1) * (eval exp2)
Exercise: Write a pointer-based type in C with exactly the same conceptual
organization as the ML type above to represent expressions.
Separately, we have a list of the value associated with each names. Here is an ML function that searches for the value that a name is bound to in a list of bindings. If no binding exists, the value zero is returned.datatype expression =
Constant of int |
Name of string |
Plus of expression * expression |
Minus of expression * expression |
Times of expression * expression;
The syntax ((n, v) :: r) is ML pattern-matching for a list whose head is the ordered pair (i.e. tuple)(n, v) and whose tail is r.fun lookup name [] = 0
| lookup name ((n, v) :: r) = if name = n then v else lookup name r
The next function evaluates an arithmetic expression according to an environment:
Be sure that you understand the ML code above completely before you start writing code for the second project.fun eval (Constant n) env = n
| eval (Name s) env = lookup s env
| eval (Plus (exp1,exp2) ) env = (eval exp1 env) + (eval exp2 env)
| eval (Times (exp1,exp2) ) env = (eval exp1 env) * (eval exp2 env)- val b1 = ("x", 2);
- val b2 = ("y", 3);
- eval (Times((Var "x"), (Var "y"))) [b1,b2];The ML response is val it = 6 : int