Partial Application

Applying only some arguments. The result is a new function.

8 topics • ~679 words

A composing stick with two blank slugs — one tagged x, one tagged y. The compositor sets a type piece into the x blank but has nothing for y yet. The stick is partially set: one blank filled, one still waiting. It is not ready to print. It is still a composing stick.

Curried functions take their arguments one at a time. But nothing says you have to supply all of them at once. If a function expects two arguments and you give it one, you get back a new function that remembers what you gave it and waits for the rest.

What Is Partial Application?

Partial application means supplying fewer arguments than a function expects. Since curried functions consume one argument at a time, applying one argument to a two-parameter function produces a new function:

(λx.λy.x y) a →β λy.a y

The outer λx consumed a, but the inner λy remains. The result is a function — not a final answer.

Result Is a Function

When you partially apply a curried function, the result always starts with λ. That leading lambda is the signal: this term is still a function, still expecting input.

(λx.λy.x y) a →β λy.a y

The λy at the front of the result means "I am a function that takes one more argument." If the result had no λ at the front, it would be a fully reduced value, not a waiting function.

Partially Apply

One round of setting type: the x blank gets the type piece, and the stick comes back with only the y blank remaining.

When you apply one argument to a curried function, you perform one beta reduction. The outer lambda is consumed and its parameter is substituted into the body:

(λx.λy.x y) a →β λy.a y

The inner lambda is untouched — it is part of the body, not the parameter being reduced. Write the result as a lambda expression.

How Many Arguments Left?

Each λ at the front of a curried function represents one expected argument. Applying one argument removes one λ. The number of remaining leading lambdas tells you how many more arguments the function still needs:

  • λx.λy.λz.M — expects 3 arguments
  • After applying one: λy.λz.M' — expects 2
  • After applying two: λz.M'' — expects 1

Apply Then Apply

Partial application gives you a function. You can then apply that function to another argument to continue reducing:

Step 1 (partial): (λx.λy.x y) a →β λy.a y Step 2 (complete): (λy.a y) b →β a b

The first application fills one blank. The second fills the last one. After both, no lambdas remain — you have a final result.

Partial vs. Full Application

The difference between partial and full application is what you get back:

  • Partial: The result is a function (starts with $\lambda$)
  • Full: The result has no leading $\lambda$ — all parameters consumed

For λx.λy.x y:

  • Applying one arg: (λx.λy.x y) a →β λy.a ypartial ($\lambda$ remains)
  • Applying both: (λx.λy.x y) a b →β a bfull (no $\lambda$ left)

Why Partial Application Matters

Consider a general function λx.λy.x y that applies x to y. Partially applying it to some specific f gives λy.f y — a specialized function that always applies f to whatever argument it receives.

This means every curried function is also a factory for more specific functions. You do not need separate definitions for each specialized case — you build them by supplying arguments one at a time.

Recognize Partial Application

Practice recognizing and performing partial application. Apply one argument to a curried function: reduce the outer lambda by substituting the argument for its parameter in the body. The inner lambda remains.

(λx.λy.M) a →β (λy.M)[x := a]

Write the resulting lambda expression.

Ready to test your understanding?

Bitwit uses spaced repetition to help you truly master concepts like this—not just read about them. Each card generates with different values, so you can't just memorize answers.

Practice Partial Application →