03 通过部分应用和柯里化让函数具象化
在输入、计算和输出这个过程中,输入是最难控制的。
部分应用和柯里化
编写一个函数时,需要传入多个实参,其中一部分实参是先明确的,另一部分是后明确的。
通过部分应用延迟实参传入
函数需要 url、data 和 callback 三个参数的输入 ,预先知道 url,不知道 data 和 callback。
function orderEventHandler(url, data, callback) {
// ..
}
提前预置已知参数,减少后面需要传入的参数数量,同时增加代码的可读性。
function fetchOrder(data, cb) {
orderEventHandler("http://some.api/order", data, cb);
}
进一步具象化
function getCurrentOrder(cb) {
getCurrentOrder({ order: CURRENT_ORDER_ID }, cb);
}
在函数式编程中,通常会使用部分应用。抽象一个 partial 工具,在先预制部分参数的情况下,后续再传入剩余的参数值。
var fetchOrder = partial(orderEventHandler, "http://some.api/order");
var getCurrentOrder = partial(fetchOrder, { order: CURRENT_ORDER_ID });
partial 工具可以借助闭包或延展操作符(spread operator)来实现。
通过柯里化每次传一个参数
var curriedOrderEvntHandler = curry(orderEventHandler);
var fetchOrder = curriedHttpEvntHandler("http://some.api/order");
var getCurrentOrder = getOrder({ order: CURRENT_ORDER_ID });
getCurrentOrder(function editOrder(order) {
/* .. */
});
其它常用的参数处理工具
在函数式编程中,参数的数量叫做 arity。
改造接口 unary
把一个接收多个参数的函数,变成一个只接收一个参数的函数。
function unary(fn) {
return function oneArg(arg) {
return fn(arg);
};
}
改造参数 constant
把值作为函数参数传入
function constant(v) {
return function value() {
return v;
};
}
promise1.then(action1).then(constant(34)).then(action3);
不做改造 identity
既不改变函数,也不改变参数。输入一个值,返回一个同样的值。
function identity(v) {
return v;
}