# 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;

``````

## 柯里化

``````const add = x => y => x + y
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，下一篇介绍一下范畴轮，和函子。

React.js编程思想
2015-11-12
2015-11-12
Vue获取DOM元素样式和样式更改示例

2017-03-13
Vue.js组件tab实现选项卡切换

2017-03-13

&lt;font face=&quot;寰�杞�闆呴粦, Arial, sans-serif &quot;&gt;2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
JavaScript教程：JS中的原型
Keith Peters 几年前发表的一篇博文，关于学习没有“new”的世界，其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法（The Standard Way） 一直以来，我们学习的在 JavaScript 里创建对...
2015-11-12
three.js实现围绕某物体旋转

2017-02-17
NodeJS参考手册pdf版

2015-11-12
Node.js学习(1)----HTTP服务器与客户端
Node.js 标准库提供了 http 模块，其中封装了一个高效的 HTTP 服务器和一个简易的HTTP 客户端。http.Server 是一个基于事件的 HTTP 服务器，它的核心由 Node.js 下层 C++部分实现，而接口由 Jav...
2015-11-12
Riot.js：不足1KB的MVP客户端框架
Riot.js是一款MVP（模型-视图-呈现）开源客户端框架，其最大的特点就是体积非常小，不足1KB，虽然体积小，但它可以帮助用户构建大规模的Web应用程序。 Riot.js是由Moot公司开发，目前最新版本为v0.9.2，遵循MIT开源许...
2016-03-11