I've seen references to curried functions in several articles and blogs but I can't find a good explanation (or at least one that makes sense!)
相关问题
- Relation between Function1 and Reader Monad
- scala passing function with underscore produces a
- Combining n vectors into one vector of n-tuples
- Improve this code by eliminating nested for cycles
- Redefine list monad instance
相关文章
- Is there something like the threading macro from C
- Learning F#: What books using other programming la
- Creating a list of functions using a loop in R
- What does “exposition only” mean? Why use it?
- When to use interfaces, and when to use higher ord
- Functors in Ocaml
- Java Lambda Referencing Enclosing Object: Replace
- “Adapter” or “adaptor”?
Here's a toy example in Python:
(Just using concatenation via + to avoid distraction for non-Python programmers.)
Editing to add:
See http://docs.python.org/library/functools.html?highlight=partial#functools.partial, which also shows the partial object vs. function distinction in the way Python implements this.
A curried function is a function of several arguments rewritten such that it accepts the first argument and returns a function that accepts the second argument and so on. This allows functions of several arguments to have some of their initial arguments partially applied.
It can be a way to use functions to make other functions.
In javascript:
Would allow us to call it like so:
When this runs the
10
is passed in asx
;which means we are returned this function:
So when you call
you are really calling:
So if you do this:
it's the same as:
So our
addTen()
always adds ten to whatever we pass in. We can make similar functions in the same way:Currying is when you break down a function that takes multiple arguments into a series of functions that take part of the arguments. Here's an example in JavaScript:
This is a function that takes two arguments, a and b, and returns their sum. We will now curry this function:
This is a function that takes one argument, a, and returns a function that takes another argument, b, and that function returns their sum.
The first statement returns 7, like the add(3, 4) statement. The second statement defines a new function called add3 that will add 3 to its argument. This is what some people may call a closure. The third statement uses the add3 operation to add 3 to 4, again producing 7 as a result.
In an algebra of functions, dealing with functions that take multiple arguments (or equivalent one argument that's an N-tuple) is somewhat inelegant -- but, as Moses Schönfinkel (and, independently, Haskell Curry) proved, it's not needed: all you need are functions that take one argument.
So how do you deal with something you'd naturally express as, say,
f(x,y)
? Well, you take that as equivalent tof(x)(y)
--f(x)
, call itg
, is a function, and you apply that function toy
. In other words, you only have functions that take one argument -- but some of those functions return other functions (which ALSO take one argument;-).As usual, wikipedia has a nice summary entry about this, with many useful pointers (probably including ones regarding your favorite languages;-) as well as slightly more rigorous mathematical treatment.
If you understand
partial
you're halfway there. The idea ofpartial
is to preapply arguments to a function and give back a new function that wants only the remaining arguments. When this new function is called it includes the preloaded arguments along with whatever arguments were supplied to it.In Clojure
+
is a function but to make things starkly clear:You may be aware that the
inc
function simply adds 1 to whatever number it's passed.Let's build it ourselves using
partial
:Here we return another function that has 1 loaded into the first argument of
add
. Asadd
takes two arguments the newinc
function wants only theb
argument -- not 2 arguments as before since 1 has already been partially applied. Thuspartial
is a tool from which to create new functions with default values presupplied. That is why in a functional language functions often order arguments from general to specific. This makes it easier to reuse such functions from which to construct other functions.Now imagine if the language were smart enough to understand introspectively that
add
wanted two arguments. When we passed it one argument, rather than balking, what if the function partially applied the argument we passed it on our behalf understanding that we probably meant to provide the other argument later? We could then defineinc
without explicitly usingpartial
.This is the way some languages behave. It is exceptionally useful when one wishes to compose functions into larger transformations. This would lead one to transducers.