首页 > 解决方案 > Javascript Pipe function - why do all standard implementations return a function which takes an argument

问题描述

I have seen a lot of implementations for pipe in javascript. All of them are written in a functional programming way, starting with a function which takes all the fns to be piped as an argument and then returning a function which takes the argument to the first function. This returned function is then responsible for piping the fns.

Something like this:

pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);

Are there any issues with writing this function in a way that it does need to return a function and can just take the parameter in its arguments:

pipe = (x, ...fns) => fns.reduce((v, f) => f(v), x);

Would both of them work the same? Is one better than the other ?

标签: javascriptfunctional-programming

解决方案


The first method is more general, and as a result, probably more useful. Consider the situation in which you'd want to call some piped functions on multiple inputs, not just one:

const pipe = (x, ...fns) => fns.reduce((v, f) => f(v), x);
console.log(
  pipe(1, x => x + 2, x => x * 2),
  pipe(3, x => x + 2, x => x * 2),
);

That's ugly. A higher-order function lets you write less repetitive code:

const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
const changeNum = pipe(x => x + 2, x => x * 2);
console.log(
  changeNum(1),
  changeNum(3),
);

If you're in a situation where you don't have to call the piped function more than once, there's not much concrete benefit of one method over the other (except, perhaps, for argument typing - having arguments which are all the same, such as ...fns, may be considered to be more elegant than mixing arguments which denote fundamentally different things, such as (x, ...fns)).

That said, it's easier not to have to think about which situation you're in, in which case the standard pipe function of (...fns) => x => is preferable anyway, since it'll flexible enough for all situations, unlike the alternative.


推荐阅读