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?
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:
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 cis 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,
curryanduncurryto transform between these two representations:curryis of type((a,b) -> c) -> a -> b -> c, that is, it takes a one-argument function that takes a tuple(a, b)and returns ac, and turns it into a function of typea -> b -> c, that is a function that takes anaand returns a function that takes aband returns ac.uncurrydoes 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 applyf (a, b)aslet g = f (a)), but since writing functions in a curried way is the default in Haskell, partial application is easy and common practice.