Skip to content

Instantly share code, notes, and snippets.

@fronterior
Created February 25, 2022 22:44
Show Gist options
  • Save fronterior/88567618ee6ffdf761843603a628b9df to your computer and use it in GitHub Desktop.
Save fronterior/88567618ee6ffdf761843603a628b9df to your computer and use it in GitHub Desktop.
const isp = v => v === curry._;
const memo = fn => {
const cache = {};
return (...p) => {
const key = JSON.stringify(p);
return key in cache ? cache[key] : cache[key] = fn(...p);
}
};
function curry(fn, length = fn.length) {
if (length === 0) return fn;
const run = curry.wrap(length, (...args) => {
const placeholders = args.reduce((acc, val, idx) => isp(val) ? [...acc, idx] : acc, []);
const emptyArgsLength = length - (args.length - placeholders.length);
if (emptyArgsLength > 0) {
if (args.length - placeholders.length === 0) return run;
else {
return curry.wrap(emptyArgsLength, (...p) => curry(fn)(...p.reduce((acc, val) => {
const phIdx = args.indexOf(curry._);
if (phIdx === -1) return [...acc, val];
else {
acc.splice(phIdx, 1, val);
return acc;
}
}, args)));
}
}
else return fn(...args);
});
return run;
};
curry._ = Symbol('placeholder');
const makeFn = memo(n => eval(`fn => function _(${Array.from({length: n}, (_, i) => 'p' + i).join(',')}) {return fn(...arguments);};`));
curry.wrap = (n, fn) => makeFn(n)(fn);
const {_} = curry;
const a = (a,b,c) => a + b * c;
const f = curry(a);
const flip = curry(fn => curry((...[a, b, ...c]) => fn(b, a, ...c), fn.length));
const ff = flip(f);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment