Custom list processing
We can write our own functions to process lists in very much the same style as we wrote functions over algebraic datatypes in the previous section.
As a first example, let us write evenLength
. This function determines whether a given list has an even length:
evenLength :: [a] -> Bool evenLength [] = True evenLength (x:xs) = not (evenLength xs)
The empty list case is the base case – the empty list does have an even length. The non-empty list case is the recursive case. We determine whether the tail, xs
, has an even length and then negate its result to determine whether (x:xs)
has an even length.
It is instructive to see how a recursive function such as evenLength
is evaluated:
evenLength (1 : 2 : 3 : []) = not (evenLength (2 : 3 : [])) = not (not (evenLength (3 : []))) = not (not (not (evenLength []))) = not (not (not True)) = False
The preceding snippet shows a sequence of simplification steps...