4.12.1.4–4.12.1.5 - Partial application and function composition (Java)

4.12.1.4–4.12.1.5 - Partial application and function composition (Java)

Use one-, two- and three-argument function types to recognise when an application returns a value or another function. Then build new functions by partial application and composition, preserving the order and types in the functional notation.

Java route status: incomplete: runnable support pending. Java source tasks here are written, have no Run, and support Paper 2 functional reasoning.

One-, two- and three-argument types

The arrows in a function type tell you what remains after each argument is supplied.

A one-argument rule, square⁡:integer→integer\operatorname{square}:\mathrm{integer}\rightarrow\mathrm{integer}, returns an integer when its integer argument is supplied. Thus square⁡  5=25\operatorname{square}\;5=25. Supplying its only argument is full application; there is no remaining input to fix later.

A two-input rule can be modelled using a pair, add⁡:integer×integer→integer\operatorname{add}:\mathrm{integer}\times\mathrm{integer}\rightarrow\mathrm{integer}. A curried form expresses it as a succession of one-argument functions:

add⁡:integer→(integer→integer).\operatorname{add}:\mathrm{integer}\rightarrow(\mathrm{integer}\rightarrow\mathrm{integer}). integer→integer→integermeans the same right-associated type.\mathrm{integer}\rightarrow\mathrm{integer}\rightarrow\mathrm{integer}\quad\text{means the same right-associated type.}

The first application returns a function. The next application returns the integer result. Function-type arrows associate to the right, but successive application associates to the left: add⁡  4  7\operatorname{add}\;4\;7 means (add⁡  4)  7(\operatorname{add}\;4)\;7. It first obtains the add-4 function, then applies it to 77, giving 1111. It does not mean applying addition to the result of an application of 4.

For a three-input rule cost⁡(a,b,c)=a+bc\operatorname{cost}(a,b,c)=a+bc, its curried type is

cost⁡:integer→(integer→(integer→integer)).\operatorname{cost}:\mathrm{integer}\rightarrow(\mathrm{integer}\rightarrow(\mathrm{integer}\rightarrow\mathrm{integer})).
ExpressionType of the resultMeaning
cost⁡\operatorname{cost}integer→integer→integer→integer\mathrm{integer}\rightarrow\mathrm{integer}\rightarrow\mathrm{integer}\rightarrow\mathrm{integer}Three inputs remain
cost⁡  2\operatorname{cost}\;2integer→integer→integer\mathrm{integer}\rightarrow\mathrm{integer}\rightarrow\mathrm{integer}Fix a=2a=2; two inputs remain
cost⁡  2  3\operatorname{cost}\;2\;3integer→integer\mathrm{integer}\rightarrow\mathrm{integer}Fix a=2,b=3a=2,b=3; one input remains
cost⁡  2  3  4\operatorname{cost}\;2\;3\;4integer\mathrm{integer}Fully apply the function; result 1414

The right-associated type describes returned functions, rather than one function with a three-element tuple argument. Both representations can express the same numerical rule, but their intermediate results have different types.

Partial application and returned functions

Partial application fixes some arguments and produces a new function waiting for the others.

Partial application

Applying fewer than all the required arguments specialises a function. Its result is a function of the remaining arguments, not the final scalar result. Currying provides a convenient representation for this process.

For add⁡  4\operatorname{add}\;4, the result is the rule x↦4+xx\mapsto4+x, of type integer→integer\mathrm{integer}\rightarrow\mathrm{integer}. Applying it to 77 gives 1111. Creating the add-4 function can be useful even if no second argument is available yet. For the three-input cost rule, cost⁡  2  3\operatorname{cost}\;2\;3 produces c↦2+3cc\mapsto2+3c. Applying that function to 44 gives 1414.

Java does not automatically curry BiFunction: add.apply(4) is invalid because its apply requires two arguments. We represent the returned function explicitly with nested Function types and lambdas. In the following complete program, a -> b -> a + b first receives a and returns the lambda b -> a + b. That returned lambda retains the supplied value of a.

Continue this lesson.

You’re previewing NovaLearn without an account. Create a free account to read the rest.

Create free account