在网上搜了下js的curry 但出来的结果没有我想要的,curry在fp中是基础的一个概念.以下是按照fp中的概念在Js中的理解 和实现
什么是curry
curry就是把多个参数的函数简化为一个参数的函数
以加法函数为例子
function add(a,b){return a+ b}
直接调用 add(2,3) 可以看到函数是两个参数
经过curry
var cadd = curry(add)
此时的 调用 cadd(2)(3) 等同于add(2,3) 可以看到 cadd 的参数是一个 通过返回一个函数来收集另外一个参数 这个就是curry *****来自开源中国的diqye****
curry的实现方式
接下来我们实现curry函数
第一种是手工curry
let mul = a => b => c => a * b * c
第二种自动curry
function partial(fn,args){
return function(){
var nargs = [].slice.call(arguments)
return fn.apply(null,args.concat(nargs))
}
}
function curryN(fn,n){
return function(){
var args = [].slice.call(arguments)
if(n <= args.length ) return fn.apply(null,args)
return curryN(partial(fn,args),n-args.length)
}
}
function curry(fn){
return curryN(fn,fn.length)
}
var mul = curry(function (a,b,c){
return a * b * c
})
console.log(mul(3)(1)(4))
console.log(mul(3,1,4))
// 12
curry有哪些用途
知道了什么是curry,那么curry有哪些用途呢?
- 降低认知函数的难度
curry后的函数参数永远固定且只有一个, 不用考虑 默认参数 可选参数情况的函数了
-
增加函数和函数之间的组合性
假设以下所有函数都是 curry的
map :: (a -> b) -> [a] -> [b]
add :: Number -> Number -> Number
var add = curry(function(a,b){
return a + b;
})
var map = curry(function(fn,xs){
var r = [];
for(var i=0;i<xs.length;i++){
r.push(fn(xs[i]));
}
return r;
})
map函数 传入一个 函数 一个数组 返回 数组中每一个元素调用 函数 的返回值 的集合
add函数 传入两个函数 返回 相加之后的结果
现在要把 [1,2,3,4] 每一个元素都加上 10 ,就可以使用组合的方式(fp中叫做pointfree)
map(add(10),[1,2,3,4])
由于add(10)
正好返回一个接收一个参数的函数 放到map
中 完美的组合在了一起!
再看个filter
的例子
var filter = curry(function(fn,xs){
var r = []
for(var i = 0;i<xs.length;i++){
if(fn(xs[i])){
r.push(xs[i])
}
}
return r;
})
var lt = curry(function(a,b){
return a < b
})
filter(lt(10),[1,2,90,10,77])
输出大于10的数组 [90,77]
原文地址 http://www.diqye.com/js-curry.html