# JS函数式编程 - 函数组合与柯里化

## 链式调用

`'Hello, world!'.split('').reverse().join('') // "!dlrow ,olleH"`

```const split = (tag, xs) => xs.split(tag)
const reverse = xs => xs.reverse()
const join = (tag, xs) => xs.join(tag)

join('',reverse(split('','Hello, world!'))) // "!dlrow ,olleH"
```

## 部分应用

```const addThreeArg = (x, y, z) => x + y + z;

addTwoArg(2, 3) // 6

## 柯里化

```const add = x => y => x + y
const plusOne = add(1)
plusOne(10) // 11```

```const curry = (fn) => { // fn可以是任何参数的函数
const arity = fn.length;

return function \$curry(...args) {
if (args.length < arity) {
return \$curry.bind(null, ...args);
}

return fn.call(null, ...args);
};
};```

### 哦，柯里化。有什么用呢？

```const currySplit = curry((tag, xs) => xs.split(tag))
const split = (tag, xs) => xs.split(tag)

// 我现在需要一个函数去split ","

const splitComma = currySplit(',') //by curry

const splitComma = string => split(',', string)
```

## 函数组合

`const compose = (...fns) => (...args) => fns.reduceRight((res, fn) =>[fn.call(null, ...res)], args)[0];`

1. 接收一组函数，返回一个函数，不立即执行函数
2. 组合函数，将传递给他的函数从左到右组合。

```const compose = (f, g) => (...args) => f(g(...args))
const compose3 = (f, g, z) => (...args) => f(g(z(...args)))```

```const split = curry((tag, xs) => xs.split(tag))
const reverse = xs => xs.reverse()
const join = curry((tag, xs) => xs.join(tag))

const reverseWords = compose(join(''), reverse, split(''))

reverseWords('Hello,world!');```

Pointfree我在上一篇介绍过JS函数式编程 - 概念，也阐述了其优缺点，有兴趣的小伙伴可以看看。

### 函数组合的结合律

`compose(f, compose(g, h)) === compose(compose(f, g), h);`

```const split = curry((tag, xs) => xs.split(tag))
const reverse = xs => xs.reverse()
const join = curry((tag, xs) => xs.join(tag))

const getReverseArray = compose(reverse, split(''))

const reverseWords = compose(join(''), getReverseArray)

reverseWords('Hello,world!');```

OK，下一篇介绍一下范畴轮，和函子。

# 版权声明

## 原文标题

JS函数式编程 - 函数组合与柯里化

## 原文链接

https://segmentfault.com/a/1190000016671245

0 条评论

• ### [Maven][taglist-maven-plugin]告警[WARNING] Using legacy tag format

执行mvn clean package site时报错[WARNING] Using legacy tag format. This is not recom...

• ### 标签云

我们博客的文章（Post）模型除了通过 ForeignKey 关联了 Category（分类）外，还通过 ManyToMany 关联了 Tag（标签）。在我们的...

• ### 18.1 集群介绍

Linux集群概述 根据功能划分为两大类：高可用和负载均衡 高可用集群通常为两台服务器，一台工作，另外一台作为冗余，当提供服务的机器宕机，冗余将接替继续提供服...

• ### 如何在CDH集群中加入异构设备

在部署CDH集群或者扩容时，会遇到服务器配置不同（CPU、Memory、DISK等）的情况，那我们应该如何加入异构设备，并进行差异化的配置呢？本篇文章主要讲述如...