Look again at the type of a simple function with more than one argument:

We have been considering functions like this as taking two arguments
and returning a result. In fact, the truth is a little different. The
type **int → int →
int** can also be written as **int → (int → int)**. OCaml lets us omit the
parentheses because **→** is a right-associative
operator in the language of types. This gives us a clue.

In truth, the function`add`

is a function which, when you give it an integer, gives you a function which, when you give it an integer, gives the sum.

This would be of no particular interest to us, except for one thing: we can give a function with two arguments just one argument at a time, and it turns out to be rather useful. For example:

` OCaml`

`# let add x y = x + y`

`val add : int -> int -> int = <fun>`

`# let f = add 6`

`val f : int -> int = <fun>`

`# f 5`

`- : int = 11`

Here, we have defined a function `f`

by applying just one
argument to `add`

. This gives a function of type
**int →
int** which adds six to any number. We then apply
`5`

to this function, giving `11`

. When defining
`f`

, we used *partial application* (we applied only
some of the arguments). In fact, even when applying all the arguments at
once, we could equally write `(add 6) 5`

rather than
`add 6 5`

. We can add six to every element in a list:

`map (add 6) [10; 20; 30]`

Here, `add 6`

has the type **int →
int**, which is an appropriate type to be the first
argument to `map`

when mapping over a list of integers. We
can use partial application to simplify some examples from earlier in
the book. We mentioned that you can write, for example,
`( * )`

to produce a function from an operator. It has type
**int →
int → int**. We may
partially apply this function, so instead of writing

`map (fun x -> x * 2) [10; 20; 30]`

we may write

`map (( * ) 2) [10; 20; 30]`

Recall the function to map something over a list of lists from the questions to Chapter 6:

With partial application, we can write

Can you see why? The partially applied function `map f`

is
of type ** α list → β
list**, which is exactly the right type to pass to

`map`

when mapping over lists of lists. In fact, we can go
even further and write:Here, `map (map f)`

has type ** α
list list → β list list** so when
an

`f`

is supplied to `mapl`

, a function is
returned requiring just the list. This is partial application at work
again.You can see the real structure of multiple-argument functions, by
writing `add`

using anonymous functions:

This makes it more obvious that our two-argument `add`

function is really just composed of one-argument functions, but
`let add x y = x + y`

is much clearer! We can apply one or
more arguments at a time, but they must be applied in order. Everything
in this chapter also works for functions with more than two
arguments.

The function `f x y`

has type ** α
→ β →
γ** which can
also be written

`f`

(which is called partial
application), or apply both at once. When we write
`let`

` f x y = …`

this is just
shorthand for
`let`

` f = `

`fun`

` x -> `

`fun`

` y -> …`

Rewrite the summary paragraph at the end of this chapter for the three argument function

`g a b c`

.Recall the function

`member x l`

which determines if an element`x`

is contained in a list`l`

. What is its type? What is the type of`member x`

? Use partial application to write a function`member_all x ls`

which determines if an element is a member of all the lists in the list of lists`ls`

.Why can we not write a function to halve all the elements of a list like this:

`map (( / ) 2) [10; 20; 30]`

? Write a suitable division function which can be partially applied in the manner we require.Write a function

`mapll`

which maps a function over lists of lists of lists. You must not use theconstruct. Is it possible to write a function which works like`let rec`

`map`

,`mapl`

, or`mapll`

depending upon the list given to it?Write a function

`truncate`

which takes an integer and a list of lists, and returns a list of lists, each of which has been truncated to the given length. If a list is shorter than the given length, it is unchanged. Make use of partial application.Write a function which takes a list of lists of integers and returns the list composed of all the first elements of the lists. If a list is empty, a given number should be used in place of its first element.