30 CHAPTER 3. FURTHER CAML
Note that the following is not a correct definition of hd. In fact, it constrains
the input list to have exactly two elements for matching to succeed, as can be seen
by thinking of the version in terms of the constructors:
#let hd [x;y] = x;;
Toplevel input:
>let hd [x;y] = x;;
> ^^^^^^^^^^^^
Warning: this matching is not exhaustive.
hd : ’a list -> ’a = <fun>
#hd [5;6];;
it : int = 5
#hd [5;6;7];;
Uncaught exception: Match_failure
Pattern matching can be combined with recursion. For example, here is a func-
tion to return the length of a list:
#let rec length =
fun [] -> 0
| (h::t) -> 1 + length t;;
length : ’a list -> int = <fun>
#length [];;
it : int = 0
#length [5;3;1];;
it : int = 3
Alternatively, this can be written in terms of our earlier ‘destructor’ functions
hd and tl:
#let rec length l =
if l = [] then 0
else 1 + length(tl l);;
This latter style of function definition is more usual in many languages, notably
LISP, but the direct use of pattern matching is often more elegant.
Some other classic list functions are appending (joining together) two lists, map-
ping a function over a list (i.e. applying it to each element) and reversing a list.
We can define all these by recursion: