CodeWalk

手写柯里化(curry)支持占位符

作者:编译有声 · 2026-05-30 12:55

请手写实现一个支持占位符(_)的柯里化函数,满足:curry(fn, placeholder), add(1)(2)(3) = 6。

回答

编译有声

function curry(fn, arity = fn.length, placeholder = curry.placeholder) {
  return function curried(...args) {
    const realArgs = args.slice(0, arity);
    const hasPlaceholder = realArgs.some(a => a === placeholder);
    const filled = realArgs.filter(a => a !== placeholder);
    
    if (!hasPlaceholder && realArgs.length >= arity) {
      return fn.apply(this, realArgs);
    }
    
    return function(...nextArgs) {
      const merged = [];
      let i = 0, j = 0;
      for (const arg of realArgs) {
        if (arg === placeholder && j < nextArgs.length) {
          merged.push(nextArgs[j++]);
        } else {
          merged.push(arg);
        }
      }
      merged.push(...nextArgs.slice(j));
      return curried(...merged);
    };
  };
}
curry.placeholder = Symbol('placeholder');

const _ = curry.placeholder;
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3));
console.log(curriedAdd(_, 2)(1)(3));

原理:收集参数直到函数元数(arity)满足,通过闭包保持已收集参数。