Managing Function Inputs
all of one
多元转一元
funtion 描述
1 | function unary (fn) { |
arrow function 描述
1 | const unary = fn => arg => fn(arg) |
explames
1 | [1, 2, 3].map(parseInt); // [1, na, na] |
one by one
怎么说捏, 这个函数, 用在延迟计算上真的很有用,比如我需要一个值, 这个值在我下一步函数用到,但是这个值, 不能污染我下一个函数啊, 那么我就可以使用组合的方式, 使用这个identity函数去组合.
1 | // function |
unchanging
某些API不让你直接传入promise, 而是要通过一个返回一个函数来调用的方式, 比如在promise链, then函数中使用另一个promise函数, 这个时候就用到了
1 | // don't work: |
FP中有个很好的工具解决这个问题
1 | // function |
Adapting Arguments to Parameters
先看一个例子
1 | function foo(x, y) { |
我知道, 我们可以在fn([3, 9])使用解构去处理数组, 但是对于FPer来说, 我们需要更强的可读性, 所以有了下面的小玩具
1 | function spreadArgs(fn) { |
但是有时候 , 我们又需要相反的操作.所以出现了下面的另一个小操作
1 | fucntion gatherArgs(fn) { |
Some Now, Some Later —- 偏函数
先看个例子
1 | function getPerson(data, cb) { |
以上的操作大家都不陌生, 就对于基本函数ajax的一个增强, 比如写死他的url, 写死, 请求方式形成get/post特定的请求方式.但是对于函数式编程来说, 这些都归为偏函数, 让我们来看偏函数这个玩具.
1 | function partial (fn, ...presetArgs) { |
好啦, 本质上就是一个闭包的使用,真的超好用. 但是, 对于js本身自带的API里其实就有类似偏函数的功能, 比如bind, 但是呢, bind存在问题,就是硬绑定this, 如果你不需要this, 那么就要传一个null作为一个占位符.你不觉得很很多余吗?
Reversing Arguments
属于部分应用函数的增强.偏函数的传入顺序是左到右, 而reversing的意思就是把传入顺序改为右到左.
1 | function reverseArgs (fn) { |
One at a time
额, 柯里化函数, 很像偏函数, 把需要多个参数的函数变成一系列连续调用的单参数函数.也就类似于, 每个函数都接受一个参数, 并且返回一个函数来接受下一个参数。
来看个场景
1 | curriedAjax('http://some.api/person')({user: CURRENT_USER_ID})(function() { console.log('成功后的回调')}) |
所以让我们来看一下curry玩具。
1 | function curry(fn, arity = fn.length) { |
回到一开始的例子, 我们用curry来解决我们遇到的问题
1 | const curriedAjax = curry(ajax) |
柯里化和偏函数的区别, 偏函数是固定某些参数, 而达到增强。而偏函数的目的是适应变化.
Visualizing Curried Functions
来让我们手动的去定义一个curried函数.
1 | funtion curriedSum (v1) { |
Why Currying and Partial Application?
类比于普通函数, sum(1, 2, 3, 4, 5), 为什么要选择, 柯里化sum(1)(2)(3)这种形式, 或者使用偏函数partial(sum, 1, 2)这种形式呢?
- 你可以在某一时刻去指定部分参数, 然后在另一时刻再去指定剩余参数. 而传统的函数则要求所有参数都必须同时存在(传入).
- 当只有一个参数时, 函数组合将会更高效, 更容易.一元函数将会更易使用.
- 其实柯里化和偏函数增加了代码的可读性,同时使代码更为简洁.
1 | ajax( |
LooseCurry
宽松的curry指的是, 我可以一次传入多个参数,而不是像之前curry每次只传入一个, 来看个实例
1 | // curry |
下面让我们看看looseCurry的定义
1 | function looseCurry(fn, arity = fn.length) { |
No curry
如果你现在有个curry化函数, 你想把它转回正常函数.
1 | function uncurry(fn) { |
用命名空间来优化偏函数和柯里化函数, 不受顺序的影响
1 | function partialProps(fn, presetArgsObj) { |
来看个使用例子
1 | function foo({ x, y, z } = {}) { |