Reputation: 10081
Is the result of a curried function a partially applied function? I understand how currying works and I though I understood how partial function application works, but I am unclear whether there is some cross over in the concepts.
My confusion has arisen from the following quote from Learn you a Haskell for great good, which conflicts with my previous understanding of the concept based on this blog post by John Skeet.
Simply speaking, if we call a function with too few parameters, we get back a partially applied function, meaning a function that takes as many parameters as we left out.
To give an example (in F# although the question is about functional programming in general)
> let add a b = a + b;;
val add : int -> int -> int
> let inc = add 1;;
val inc : (int -> int)
In this example is inc
a partially applied function?
Upvotes: 3
Views: 456
Reputation: 20721
Generally speaking, currying means transforming a two-argument function into one that takes one argument and returns another one-argument function, so that the result of calling the curried function with the first argument and then the result of this with the second argument is equivalent to calling the original (uncurried) function with both arguments. In a pseudo-C language with closures and dynamic typing (or type inference), this would look something like so:
// The original, uncurried function:
function f(a, b) { return 2 * a - b; }
// The curried function:
function g(a) {
return function(b) {
return f(a, b);
}
}
// Now we can either call f directly:
printf("%i\n", f(23, 42));
// Or we can call the curried function g with one parameter, and then call the result
// with another:
printf("%i\n", (g(23))(42));
By currying multiple times, we can reduce any multi-argument function to a nested set of one-argument functions.
In Haskell, all functions are single-argument; a construct like f a b c
is actually equivalent to ((f(a))(b))(c)
in our fictional C-with-closures. The only way to really pass multiple arguments into a function is through tuples, e.g. f (a, b, c)
- but since the syntax for curried functions is simpler, and the semantics are more flexibly, this option is seldom used.
The Haskell Prelude defines two functions, curry
and uncurry
to transform between these two representations: curry
is of type ((a,b) -> c) -> a -> b -> c
, that is, it takes a one-argument function that takes a tuple (a, b)
and returns a c
, and turns it into a function of type a -> b -> c
, that is a function that takes an a
and returns a function that takes a b
and returns a c
. uncurry
does the reverse.
Partial application isn't really a thing; it's just a name given to the situation where you have a curried function (e.g. f a b
), and instead of fully unrolling the whole chain (e.g., f 23 42
), you stop somewhere along the way, and pass the resulting function further, e.g. let g = f 23
. In order to partially-apply a function, it must be curried (you cannot partially apply f (a, b)
as let g = f (a)
), but since writing functions in a curried way is the default in Haskell, partial application is easy and common practice.
Upvotes: 3
Reputation: 8937
Short answer: inc
is a function obtained through partial application.
The result of a curried function is a value of some type in the target language (Haskell, F# or whatever), so it MAY be a function (but it may be also an integer, a boolean, ..., depending on your declaration).
About partial application... it's just a name given to function applications that return other functions, but technically it's a function application like every other. It's not even mandatory that the function you return is based on the previous arguments. Take \x -> id
for example: you always get the identity function, independently with respect to the input x
.
Upvotes: 0