I am a beginner of sml and I'm taking programming language courses at Coursera. There's a datatype and function that I don't know how to evaluate:
datatype exp = constant of int
| Negate of exp
|Add of exp * exp
|Multiply of exp * exp
fun true_of_all_constants(f,e) =
case e of
constant i => f i
| Negate e1 => true_of_all_constants(f,e1)
| Add(e1,e2) => true_of_all_constants(f,e1)
andalso true_of_all_constants(f,e2)
| Multiply(e1,e2) => true_of_all_constants(f,e1)
andalso true_of_all_constants(f,e2)
Trying to evaluate them, I always get errors:
true_of_all_constants [3,4,5];
true_of_all_constants 4;
true_of_all_constants (is_even 4, 5);
where is_even is a little helper function:
fun is_even v =
(v mod 2 = 0)
To test true_of_all_constants, what should e be replaced with? Also, could you explain what does datatype do here? I don't understand why we need "Negate" or "Add" here; why we have "exp*exp," rather than "exp+exp," for "Add?"
Fixing whitespace, the data type definition and the definition of true_of_all_constants (p, e)
become:
datatype exp =
Constant of int
| Negate of exp
| Add of exp * exp
| Multiply of exp * exp
fun true_of_all_constants (p, e) =
let fun aux (Constant i) = p i
| aux (Negate e1) = aux e1
| aux (Add (e1, e2)) = aux e1 andalso aux e2
| aux (Multiply (e1, e2)) = aux e1 andalso aux e2
in aux e end
Here constant
has been renamed to Constant
: Both will work, but naming constructors with an uppercase letter differentiates it visually from other identifiers. And I've used an inner function, aux
, to shorten the recursive expressions a bit. Instead of f
I called it p
for predicate, but that's a taste thing.
Trying to evaluate them, I always get errors
Here are some examples of expressions and evaluating them:
- val two_plus_two = Add (Constant 2, Constant 2);
- true_of_all_constants (fn i => i = 2, two_plus_two);
> val it = true : bool
- val two_times_neg_two = Multiply (Constant 2, Constant ~2);
- true_of_all_constants (fn i => i > 0, two_times_neg_two);
> val it = false : bool
- val two_four_six = Add (Constant 2, Add (Constant 4, Constant 6));
- fun is_even x = x mod 2 = 0;
- true_of_all_constants (is_even, two_four_six);
> val it = true : bool
could you explain what does datatype do here?
I think you should refer to a book or tutorial here.
For example, ML for the Working Programmer, ch. 4 (free PDF) deals with datatype
definitions.
I don't understand why we need "Negate" or "Add" here
I don't know, either. The problem you're given in the course is entirely hypothetical.