Note: @ftor answered his/her own question. This is a direct companion to that answer.
You're already a genius
I think you might've re-imagined the partial
function – at least, in part!
const partial = (f, ...xs) => (...ys) => f(...xs, ...ys);
and it's counter-part, partialRight
const partialRight = (f, ...xs) => (...ys) => f(...ys, ...xs);
partial
takes a function, some args (xs
), and always returns a function that takes some more args (ys
), then applies f
to (...xs, ...ys)
Initial remarks
The context of this question is set in how currying and composition can play nice with a large user base of coders. My remarks will be in the same context
just because a function may return a function does not mean that it is curried – tacking on a _
to signify that a function is waiting for more args is confusing. Recall that currying (or partial function application) abstracts arity, so we never know when a function call will result in the value of a computation or another function waiting to be called.
curry
should not flip arguments; that is going to cause some serious wtf moments for your fellow coder
if we're going to create a wrapper for reduce
, the reduceRight
wrapper should be consistent – eg, your foldl
uses f(acc, x, i)
but your foldr
uses f(x, acc, i)
– this will cause a lot of pain amongst coworkers that aren't familiar with these choices
For the next section, I'm going to replace your composable
with partial
, remove _
-suffixes, and fix the foldr
wrapper
Composable functions
const partial = (f, ...xs) => (...ys) => f(...xs, ...ys);
const partialRight = (f, ...xs) => (...ys) => f(...ys, ...xs);
const comp = (f, g) => x => f(g(x));
const foldl = (f, acc, xs) => xs.reduce(f, acc);
const drop = (xs, n) => xs.slice(n);
const add = (x, y) => x + y;
const sum = partial(foldl, add, 0);
const dropAndSum = comp(sum, partialRight(drop, 1));
console.log(
dropAndSum([1,2,3,4]) // 9
);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…