const trace = label => value => {
console.log(`${ label }: ${ value }`);
return value;
};
现在我们可以使用这个来检查函数了:
const compose = (...fns) => x => fns.reduceRight((y, f) => f(y), x);
const trace = label => value => {
console.log(`${ label }: ${ value }`);
return value;
};
const g = n => n + 1;
const f = n => n * 2;
/*
Note: function application order is
bottom-to-top:
*/
const h = compose(
trace('after f'),
f,
trace('after g'),
g
);
h(20);
/*
after g: 21
after f: 42
*/
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
const trace = label => value => {
console.log(`${ label }: ${ value }`);
return value;
};
const g = n => n + 1;
const f = n => n * 2;
/*
Now the function application order
runs top-to-bottom:
*/
const h = pipe(
g,
trace('after g'),
f,
trace('after f'),
);
h(20);
/*
after g: 21
after f: 42
*/
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
const trace = value => label => {
console.log(`${ label }: ${ value }`);
return value;
};
const g = n => n + 1;
const f = n => n * 2;
const h = pipe(
g,
// the trace() calls can't be point-free,
// because arguments are expected in the wrong order.
x => trace(x)('after g'),
f,
x => trace(x)('after f'),
);
h(20);
如果不想这样,可以使用名为flip()的函数解决该问题,该函数只是翻转两个参数的顺序:
const flip = fn => a => b => fn(b)(a);
现在我们可以创建一个flippedTrace函数:
const flippedTrace = flip(trace);
再这样使用这个flippedTrace:
const flip = fn => a => b => fn(b)(a);
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
const trace = value => label => {
console.log(`${ label }: ${ value }`);
return value;
};
const flippedTrace = flip(trace);
const g = n => n + 1;
const f = n => n * 2;
const h = pipe(
g,
flippedTrace('after g'),
f,
flippedTrace('after f'),
);
h(20);
const traceAfterG = value => {
const label = 'after g';
console.log(`${ label }: ${ value }`);
return value;
};
如果我们为traceAfterG交换trace('after g'),那就意味着同样的事情:
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
const trace = label => value => {
console.log(`${ label }: ${ value }`);
return value;
};
// The curried version of trace()
// saves us from writing all this code...
const traceAfterG = value => {
const label = 'after g';
console.log(`${ label }: ${ value }`);
return value;
};
const g = n => n + 1;
const f = n => n * 2;
const h = pipe(
g,
traceAfterG,
f,
trace('after f'),
);
h(20);