偏函数
function partial( fn, ...prevArgs ) {
return function partialed( ...lastArgs ) {
return fn( ...prevArgs, ...lastArgs )
}
}
颠倒实参顺序
function reverseArgs( fn ) {
return function argsReversed( ...args ) {
return fn( ...args.reverse() )
}
}
组合函数
function compose( ...fns ) {
return function composed(result) {
let list = fns.slice()
while( list.length > 0 ) {
result = list.pop()( result )
}
return result
}
}
组合函数 reduce实现
function compose( ...fns ) {
let list = fns.slice()
return list.reverse().reduce( function reducer( fn1, fn2 ) {
return function composed( ...args ) {
return fn2( fn1( ...args ) )
}
} )
}
pipe(...) VS compose(...)
pipe() 从左向右执行
function pipe( ...fns ) {
return function piped( result ) {
let list = fns.slice()
while( list.length > 0 ) {
result = list.shift()( result )
}
return result
}
}
右偏函数应用
function partialRight( fn, ...prevArgs ) {
return reverseArgs(
partial( reverseArgs( fn ), ...prevArgs.reverse() )
)
}
function foo(x,y,z) {
var rest = [].slice.call(arguments, 3)
console.log(x,y,z,rest)
}
var f = partialRight( foo, 'z:last' )
f(1,2) // 12 'z:last' []
f(1) // 12 'z:last' undefined []
柯理化
function curry( fn, arity = fn.length ) {
return ( function nextCurried( prevArgs ) {
return function curried(nextArg) {
var args = prevArgs.concat( [nextArg] )
if( args.length >= arity ) {
return fn( ...args )
}else{
return nextCurried( args )
}
}
} )( [] )
}
把空数组[]当做 prevArgs的初始实参集合,接收的nexArg同 prevArgs组成 args,当args.length小与 arity(原函数fn(...)被定义和期望的形参数量),返回另一个curried函数,用来接收下一个nextArg实参
function add(x,y) {
return x + y
}
// 偏函数
[1,2,3].map( partical(add,2) ) //[3,4,5]
// 柯理化
[1,2,3].map( curry(add)(2) ) // [3,4,5]
松散的柯理化
可以多参,并且可以超过预设参数 长度
var curryed = looseCurry( add, 5 )
curryed(1)( 2,3 )(4,5)
curryed(1,2)(3,4)(5,6)
function looseCurry( fn, arity = fn.lenght ) {
return ( function nextCurried( prevArgs ){
return function curried( ...nextArgs ) {
var args = prevArgs.concat( nextArgs )
if( args.length >= arity ) {
return fn( ...args )
}else {
return nextCurried( args )
}
}
})( [] )
}
反柯理化
f(1)(2)(3) => g(1,2,3)
function uncurry(fn) {
return function uncurried( ...args ) {
var ret = fn;
for( let i=0;i<args.length;i++ ) {
ret = ret( args[i] )
}
return ret
}
}
网友评论