柯里化函数

函数柯里化

柯里化(Currying) 是一种将接受 多个参数的函数 转换为一系列 接受单个参数的函数 的技术,其核心思想是
分步传递参数,逐步生成更具体的函数。这种技术由数学家 Haskell Curry 提出,广泛应用于函数式编程中,以提高代码的复用性和组合性。

基本定义
//普通函数  一次传入全部参数
function add(a, b, c) 
{
 	return a + b + c; 
}
add(1, 2, 3); // 6
//柯里化之后
function curriedAdd(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    };
  };
}
curriedAdd(1)(2)(3); // 6

//用箭头函数简化上面写法 柯里化
let  curriedAdd = (a)=>(b)=>(c)=>a+b+c

在这里插入图片描述

优缺点

在这里插入图片描述
在这里插入图片描述

柯里化的实现方式

1. 手动实现 通过闭包和递归逐步收集参数:
function curry(fn) {
  return function curried(...args) {
    // 参数足够时执行原函数,否则返回新函数继续收集参数
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...nextArgs) {
        return curried.apply(this, args.concat(nextArgs));
      };
    }
  };
}
 
// 使用示例
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6
console.log(curriedAdd(1, 2)(3)); // 6
2. ES6 箭头函数简化 利用箭头函数隐式返回特性:
const curry = (fn) => 
  curried = (...args) => 
    args.length >= fn.length 
      ? fn(...args) 
      : (...nextArgs) => curried(...args, ...nextArgs);
 
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6

应用场景

1. 参数复用 固定部分参数,生成特定功能的函数:
const curry = (fn) => 
  curried = (...args) => 
    args.length >= fn.length 
      ? fn(...args) 
      : (...nextArgs) => curried(...args, ...nextArgs);
 
// 通用日志函数
const log = (level, message) => console.log(`[${level}] ${message}`); 
// 柯里化生成特定级别的日志函数
const debugLog = curry(log)('DEBUG');
debugLog('User logged in'); // [DEBUG] User logged in 
const errorLog = curry(log)('ERROR');
errorLog('Database connection failed'); // [ERROR] Database connection failed
2. 延迟执行 动态组合参数,最后统一执行:
const curry = (fn) => 
  curried = (...args) => 
    args.length >= fn.length 
      ? fn(...args) 
      : (...nextArgs) => curried(...args, ...nextArgs);
// 为了方便理解,我把参数收集去掉
const curry = fn => m=>u=>d=>fn(m,u,d)
// 发送 API 请求
const sendRequest = (method, url, data) => { /* ... */ };
 
// 柯里化生成 POST 请求函数
const post = curry(sendRequest)('POST');
post('/api/users')({ name: 'Alice' });
 
// 进一步生成特定路径的 POST 函数
const postToUsers = post('/api/users');
postToUsers({ name: 'Bob' });
3. 函数组合 结合 compose 或 pipe 实现复杂逻辑:
const curry = fn=>fn;
// 组合多个函数
const compose = (...fns) => x => fns.reduce((v, f) => f(v), x);
 
// 柯里化处理数据流
const toUpperCase = str => str.toUpperCase();
const exclaim = str => str + '!';
const emphasize = compose(curry(exclaim), curry(toUpperCase));
 
console.log(emphasize('hello')); // "HELLO!"

在这里插入图片描述

// 柯里化
const add = a => b => c => a + b + c;
add(1)(2)(3); // 6
 
//add(1) 返回 b => c => a + b + c
//add(1)(2) 返回  c => a + b + c
//add(1)(2)(3) 返回 a + b + c
// 部分应用
const partialAdd = (a, b) => c => a + b + c;
partialAdd(1, 2)(3); // 6
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐