**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.

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.

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 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.:

Thu Apr 17 14:21:55 PDT 1997