# 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，下一篇介绍一下范畴轮，和函子。

1.2k 声望
91 粉丝
0 条评论