> This hints that they might be 'dual' notions, in a Mathematical sense. Maybe I should dub it "cocurrying"?
After a little more thought I've realised that this is exactly uncurrying of return values.
When we uncurry, we take a bunch of arguments at once and supply them one-at-a-time to our function, for example "uncurry(foo)(a, b, c, d)" becomes "foo(a)(b)(c)(d)".
Note that this is identical to the calling convention of a curried function, hence the name uncurrying. In this way, it makes sense to uncurry the return value of curry:
// Pass 3 values to a curried function which just-so-happens to return
// other functions
curry(function(w, x) {
return function(y) {
return function(z) {
return w + x + y + z;
};
};
})(1, 2, 3, 4);
// Take the first 2 arguments to be w and x
(function(w, x) {
return function(y) {
return function(z) {
return w + x + y + z;
};
};
})(1, 2)(3, 4);
// Apply the first function
(function(y) {
return function(z) {
return 1 + 2 + y + z;
};
})(3, 4);
// The above version will ignore 4 and wait for another z.
// This is why we need to uncurry it.
uncurry(function(y) {
return function(z) {
return 1 + 2 + y + z;
};
})(3, 4);
// Now we can execute it properly
(function(y) {
return function(z) {
return 1 + 2 + y + z;
};
})(3)(4);
(function(z) {
return 1 + 2 + 3 + z;
})(4);
10;
Now, given our implementations of curry, we don't actually have to uncurry a function explicitly: we can call "foo(a, b, c, d)" even if "foo" is curried. Hence we can just pass all the arguments straight into the return value
assuming that it is uncurried.
This will work for regular Javascript functions and those which we've curried. The only thing it won't work for is functions which have been hard-coded in a curried form; these will need to be sent through an uncurry function first (which we can do via composition).