We've already seen how to model a list of person records in Chapter 5, Putting Alternative Values in Types, but that data structure was limited to holding only values of person records. Ideally, we want a data structure that can hold values of any type, so that we don't have to re-implement the type and its operations for every possible element type. We can accomplish this by parameterizing the list type by the element type, as follows:
/* src/Ch06/Ch06_List.re */
type list('a) = Cons('a, list('a)) | Empty; /* (1) */
/* (2) */
let people = Ch04_RecordLiterals.(Cons(bob, Cons(jim, Cons(tom, Empty))));
/* (3) */
let greetOne({Ch04_RecordLiterals.id, name}) = print_endline(
{j|Hello, $name with ID $id!|j});
let rec greetAll(people) = switch (people) {
| Cons(person, people) => { /* (4) */
greetOne(person);
greetAll(people...