Cambridge University Press 1.1 Time Clock User Manual


 
28 CHAPTER 3. FURTHER CAML
#let true_1 = true;;
true_1 : bool = true
#let false_1 = false;;
false_1 : bool = false
#(fun true_1 -> 1 | false_1 -> 0) (4 < 3);;
Toplevel input:
>(fun true_1 -> 1 | false_1 -> 0) (4 < 3);;
> ^^^^^^^
Warning: this matching case is unused.
it : int = 1
In general, the unit element (), the truth values, the integer numerals, the string
constants and the pairing operation (infix comma) have constructor status, as well
as other constructors from predefined recursive types. When they occur in a pattern
the target value must correspond. All other identifiers match any expression and in
the process become bound.
As well as the varstructs in function expressions, there are other ways of per-
forming pattern matching. Instead of creating a function via pattern matching and
applying it to an expression, one can perform pattern-matching over the expression
directly using the following construction:
match expression with pattern
1
->E
1
| ·· · | pattern
n
->E
n
The simplest alternative of all is to use
let pattern = expression
but in this case only a single pattern is allowed.
3.4.2 Recursive types
The previous examples have all been recursive only vacuously, in that we have not
defined a type in terms of itself. For a more interesting example, we will declare a
type of lists (finite ordered sequences) of elements of type ’a.
#type (’a)list = Nil | Cons of ’a * (’a)list;;
Type list defined.
Let us examine the types of the constructors:
#Nil;;
it : ’a list = Nil
#Cons;;
it : ’a * ’a list -> ’a list = <fun>
The constructor Nil, which takes no arguments, simply creates some object of
type (’a)list which is to be thought of as the empty list. The other constructor
Cons takes an element of type ’a and an element of the new type (’a)list and
gives another, which we think of as arising from the old list by adding one element
to the front of it. For example, we can consider the following: