Generalizing by Parameterizing


How can we generalize this example?

One obvious idea is to make the start and stop indices into parameters. We'll neaten up the function a little while we're at it:


Now, what if we wanted to do something similar, but using the fact function instead of the fib function?

Functions as Parameters

Solution: abstract with respect to the fib function.


Note that the first argument of funcs_p_to_q is (automatically) given the polymorphic type int->'a, which is tied to the output type (int *'a) list. So we can also write something like this:


Choosing a parameterization

We could also have chosen a more general parameterization that doesn't force the output to be a list of pairs:


Now we can get the effect of the original function by passing a more complicated function as parameter:


Or use an anonymous function:


Higher-order mapping functions

Higher-order functions are great for operating on entire lists ``at once'':

Function map applies a function to each member of a list and returns the resulting list.


A variant of map is a function that applies a binary function to corresponding elements of two lists:


Higher-order functions with predicates

Function filter applies a predicate (a function that returns a bool) to each member of a list and returns a list containing just the matching members.


Function forall takes a predicate and a list and returns true iff the predicate is true of every member. Note the ``short-circuiting.'' exists can be defined similarly.


List Reduction

Recall these examples:


We can now see how to generalize these functions to a common higher-order function.

Both operate over lists, working from the right (tail) end, calculating a result.

tex2html_wrap_inline133 At each list item, the result is calculated by applying a binary combining function f (here + or ^) to the list item and the result previously calculated for the tail.

tex2html_wrap_inline133 A special seed value s (here 0 or "") is needed to start off the computation at the tail of the list.

List Reduction (Continued)

Abstracting over the binary function and the seed value, we get the following function:


If the list has contents tex2html_wrap_inline137 then we are computing


If we wrote the list using a prefix form of ``cons'' it would look like this:


Note that we can view reduce(f,s,l) as the result of replacing cons with f and nil with s.

Name that reduce!

Notice that the type of reduce is actually more general than we needed for these examples: the computed value and the list elements do not need to be of the same type:


A surprising number of functions can be written as instances of reduce,e.g.:


Andrew P. Tolmach
Thu Apr 17 14:21:55 PDT 1997