Skip to 0 minutes and 7 secondsWIM: Hello, everyone. In this short video, we are going to introduce two new concepts that are slightly more advanced. And they are currying and partial application. So consider the function signature like this, where we have a type X, Y, Z, and return value of type A. So this is a function that takes three arguments of three different types and produces a return value of type A. However, the arrow here in this type signature is meaningful. And also, it has a certain associativity. In fact, it associates to the right.
Skip to 0 minutes and 55 secondsAnd that means that, actually, we can write this expression also like this, which means that we actually can consider f as a function that takes an element of type X and returns a function of Y to function of Z to A. Similar, this return function, Y, can be considered both as a function of Y and Z to A or as a function of Y to Z to A. So this idea that you can always rewrite the function of a single argument returning another function is called currying. To illustrate this on an actual function, it's easiest to use lambda functions. So suppose we have a lambda function of X, Y, and Z, and function body is completely irrelevant.
Skip to 1 minute and 50 secondsThen to rewrite this, so that this becomes a function of a single argument. We create a new lambda function, which is this one. So the body remains completely untouched. And we can rewrite this inner function once more.
Skip to 2 minutes and 9 secondsAnd in this way, we have created a function of a single argument which returns a function of a single argument which returns a function of a single argument, which eventually returns the value. So this is the typical technique known as currying you use to transform multi-argument functions into single argument functions. So it's named after the logician Haskell Curry. But actually, he wasn't the first to invent this. The first one to invent this technique was called Moses Schonfinkel, another logician. But well, his name wasn't so catchy, so they decided to go with currying. Another concept closely related to currying is that of partial application.
Skip to 2 minutes and 52 secondsFor example, consider the function sq, which takes X and Y and returns the sum of the squares.
Skip to 3 minutes and 5 secondsThis function can actually, again, be slightly rewritten as-- because the function application, actually, is left associative. That means that what we have here is a function in its own right that operates on Y. So we can do other things like, for instance, say OK. Let's define sq4 as sq4. And now sq4 is a new function which just takes one argument. If we now call Sq4 on value three, it will return 25. This is an example of partial application. So basically, we've applied four to the function argument x, but we haven't applied anything to y, and the result is a new function. And then we can use this new function for doing our computation.
Skip to 4 minutes and 6 secondsSo this technique of partial application is really used a lot in functional programming in Haskell, and it's the reason why you can write things, for instance, like this.
Skip to 4 minutes and 20 secondsSo here, the times two is partial application of the function multiplication that we use as an operator here, so it takes two arguments and returns an argument. We have applied it partially, using the two. We get a new function, which we can use in the map, because map requires functions with a single argument. And so we have a function that doubles the elements of a list.
Skip to 4 minutes and 46 secondsSo this was just to give you a quick intuition on these key concepts of currying and partial application.
Curry is on the menu
Partial Application and Currying
Consider a type signature of a function with three arguments:
f :: X -> Y -> Z -> A
The arrow “->” is right-associative, so this is the same as:
f :: X -> (Y -> (Z -> A))
What this means is that we can consider
f as a function with a single argument of type
X which returns a function of type
The technique of rewriting a function of multiple arguments into a sequence of functions with a single argument is called currying. We can illustrate this best using a lambda function:
\x y z -> ... \x -> (\y z -> ...) \x -> (\y -> (\z -> ... ))
The name “currying”, is a reference to logician Haskell Curry. The concept was actually proposed originally by another logician, Moses Schönfinkel, but his name was not so catchy.
Partial application means that we don’t need to provide all arguments to a function. For example, given
sq x y = x*x+y*y
We note that function application associates to the left, so the following equivalence holds
sq x y = (sq x) y
We can therefore create a specialised function by partial application of x:
sq4 = sq 4 -- = \y -> 16+y*y sq4 3 -- = (sq 4) 3 = sq 4 3 = 25
This is why you can write things like:
doubles = map (*2) [1 .. ]
© Wim Vanderbauwhede