A function by itself can't be "partially applied" or not. It's a meaningless concept.
When you say that a function is "partially applied", you refer to how the function is called (aka "applied"). If the function is called with all its parameters, then it is said to be "fully applied". If some of the parameters are missing, then the function is said to be "partially applied".
For example:
-- The function `take` is fully applied here:
oneTwoThree = take 3 [1,2,3,4,5]
-- The function `take` is partially applied here:
take10 = take 10 -- see? it's missing one last argument
-- The function `take10` is fully applied here:
oneToTen = take10 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,42]
The result of a partial function application is another function - a function that still "expects" to get its missing arguments - like the take10
in the example above, which still "expects" to receive the list.
Of course, it all gets a bit more complicated once you get into the higher-order functions - i.e. functions that take other functions as arguments or return other functions as result. Consider this function:
mkTake n = take (n+5)
The function mkTake
has only one parameter, but it returns another function as result. Now, consider this:
x = mkTake 10
y = mkTake 10 [1,2,3]
On the first line, the function mkTake
is, obviously, "fully applied", because it is given one argument, which is exactly how many arguments it expects. But the second line is also valid: since mkTake 10
returns a function, I can then call this function with another parameter. So what does it make mkTake
? "Overly applied", I guess?
Then consider the fact that (barring compiler optimizations) all functions are, mathematically speaking, functions of exactly one argument. How could this be? When you declare a function take n l = ...
, what you're "conceptually" saying is take = \n -> \l -> ...
- that is, take
is a function that takes argument n
and returns another function that takes argument l
and returns some result.
So the bottom line is that the concept of "partial application" isn't really that strictly defined, it's just a handy shorthand to refer to functions that "ought to" (as in common sense) take N arguments, but are instead given M < N arguments.
take
. You could for example writetake 4 [2,3,5,7,11,13,17,19]
and it would evaluate to[2,3,5,7]
. However, you could also definetakeFour = take 4
and now you have a partially appliedtake
function. It's partially applied because it's not been given the second input. ThistakeFour
function can be applied to any list and it'll return the first four elements of that list. What we essentially did was create a specialized version oftake
by only givingtake
one argument instead of two. – Cametake 4 primes
is really an expression consisting of two function calls;take 4
returns a new function which is then applied toprimes
(the equivalent explicitly parenthesized expression is(take 4) primes
). The term "partial application" is used, though, to describe the situation where you aren't making all the function calls needed to ultimately get a non-function value. – Osuna