[函数式编程] 为什么要柯里化?

上一篇,我们简单看了下柯里化函数是什么。

来到这里,你大概带着为什么要柯里化的问题。现在,我们一块来解答下它。

在函数式编程中,柯里化函数是为了函数组合。小函数经过柯里化后,成了可组合的"积木块",再由组合函数把它们拼装成复杂逻辑的大函数。

我们来看一个格式化用户名的例子。首先我们创建三个小函数,他们分别在用户名前添加前缀,添加后缀到用户名后面,以及把用户名转成大写。

js 复制代码
let toUpperCase = str => str.toUpperCase();
let append = (suffix, str) => str + suffix;
let prepend = (prefix, str) => prefix + str;

现在,我们组合调用他们,确实,我们格式化姓名Addy,得到结果'Hello, ADDY!'

js 复制代码
prepend('Hello,', toUpperCase(append('!', 'Addy')))

但上述代码存在2个问题

  • 如果我需要对另一个名字,比如'tom',做同样的格式化,需要再次完全地调用一遍
  • 函数嵌套式的调用方式,可读性弱

如何解决这两个问题

其实,我们可以通过柯里化函数,与函数组合工具,把这三个函数组合成一个完整的格式化函数。

下面我们写一个函数组合工具

js 复制代码
const compose = (...fns) => x => fns.reduceRight((v, fn) => fn(v), x);

组合前,柯里化这些小函数是必要的

js 复制代码
const curry = fn => (...args) =>
  args.length >= fn.length
    ? fn(...args)
    : (...next) => curry(fn)(...args, ...next);
    
toUpperCase = curry(toUpperCase);
append = curry(append);
prepend = curry(prepend);

最后,组合这三个小函数,得到一个完整的格式化函数

js 复制代码
const formatName = compose(
  append('!'),
  toUpperCase,
  prepend('Hello, ')
);

console.log(formatName('Addy')); // Hello, ADDY!
console.log(formatName('tom')); // Hello, TOM!

以上代码,由compose组合的函数们,以顺序列表的形式出现,即他们被执行的顺序,可读性强。另外,最终得到的组合函数,可以被复用。

总结

由此可见,函数式编程中,柯里化是为了组合小函数(功能)为复合功能的大函数。如果你是一个细心的读者,可能会发问,那如何让循环,条件,异步也成为可组合的函数呢?这个问题我们下回讨论。

相关推荐
ℋᙚᵐⁱᒻᵉ鲸落4 小时前
移动端滑动手势冲突:overflow: auto导致外层横向滑动失效
前端·javascript·css·vue.js·html
默_笙5 小时前
🎃 前端学了 Next.js,后端该学啥?NestJS 就是 Node 版的蜜雪冰城
前端·javascript
前端snow6 小时前
ai agent --- 实现 openclaw 定时间效果
前端
码云之上7 小时前
换模型之后,Chatbot 为什么要自己做 compact?
前端·agent·前端工程化
星栈7 小时前
自定义 UI-UX-Pro-Max 的 CSV 知识库,把 AI 生成的后台拉回行业该有的样子
前端·agent·weui
研☆香7 小时前
简单的图片上传 删除 预览
前端
ITresearchGuest7 小时前
我用 AI 一小时写了一个世界杯数据可视化平台|前端 VibeCoding 初体验
前端·人工智能·信息可视化
慧一居士8 小时前
Vite项目中使用Less步骤,详细使用示例
前端·css
花间相见9 小时前
【LangChain组件03】—— LangChain Agents 执行与状态:工作流程与状态管理实战
java·前端·langchain
kyriewen9 小时前
面试官让我用 AI 重构一个 8 年陈的 React 组件——他说他不看代码,只看我会不会拆
前端·javascript·面试