Function Composition: compose/pipe

https://www.educative.io/answers/function-composition-in-javascript

Function composition is an approach where the result of one function is passed on to the next function, which is passed to another until the final function is executed for the final result. Function compositions can be composed of any number of functions.


Traditional approach

Traditionally, function composition follows this format:

const double = x => x * 2

const square = x => x * x

// Tradition approach

var output1 = double(2);

var output2 = square(output1);

console.log(output2);

// variant two

var output_final = square(double(2));

console.log(output_final);

In the code above, we can see that we need to call the double function followed by the square function to square a term that has been doubled. We can do this by either assigning the values individually in variables and calling functions onto them (lines 4 to 5), or we could use a more direct approach like on line 8.


https://itnext.io/write-better-javascript-function-composition-with-pipe-and-compose-93cc39ab16ee

compose
compose参数:扁平化的函数,from right to left
层级嵌套的函数调用

compose函数: 把层级嵌套的函数调用(一个函数的运行结果当作实参传给下一个函数的操作)扁平化

example:

1.调用compose([a, b, c])(param)和a(b(c(param)))效果相同

2.compose(f1,f2)(4),执行结果是f1(f2(4))

3.

let x = fn1(6);

x = fn2(x);

x = fn1(x);

x = fn3(x);

用一个函数解决这种问题,形如:compose(fn1, fn2, fn1, fn3)(6);

4.

let fn1 = (x) => x + 10

let fn2 = (x) => x * 10

let fn3 = (x) => x / 10

console.log(fn3(fn1(fn2(fn1(6)))));


Alternate approach

Another approach is to use the compose and pipe functions.

compose function

compose function takes any number of functions and invokes them all one after the other:

// function composition of any number of functions

const compose = (...fns) => x => fns.reduceRight((y, f) => f(y), x);

const double = x => x * 2

const square = x => x * x

// function composition

var output_final = compose(square, double)(2);

console.log(output_final);

In the code above, we can see that the compose function is implemented using a general approach on line 2, so now it can take any number of functions. The output remains the same as before even with using this implementation.


pipe function

On the other hand, we can reverse the order of the function invocation by using the pipe function:

reduce: from left to right

// function composition using pipe of any number of functions

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

const double = x => x * 2

const square = x => x * x

// function pipe

var output_final = pipe(square, double)(2);

console.log(output_final);

In the code above, we can see that the pipe function is implemented using a general approach on line 2, so it can now take any number of functions. This is similar to the previous compose function, except that it uses reduce instead of the reduceRight method. The output is different in this case because the square function is invoked before the double function while, in our compose function, it was in the opposite order.


Function composition enabling piping

// Building-blocks to use for composition

const double=x=>2*x

const triple=x=>3*x

const quadruple=x=>4*x

// Function composition enabling pipe functionality

const pipe=(...functions)=>input=>functions.reduce((acc,fn)=>fn(acc),input)

// Composed functions for multiplication of specific values

const multiply6=pipe(double,triple)

const multiply9=pipe(triple,triple)

const multiply16=pipe(quadruple,quadruple)

const multiply24=pipe(double,triple,quadruple)

// Usage

multiply6(6)// 36

multiply9(9)// 81

multiply16(16)// 256

multiply24(10)// 240


Libraries for function composition

Given the importance of function composition, we may use libraries that have already completed the implementation of both the compose and pipe functions. The following libraries might help.

Ramda: compose and pipe

Lodash: flowRight (compose) and flow (pipe)

These libraries can be used to avoid implementing either function so you can focus on the uses of it.

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 长久以来,面向对象在 JavaScript 编程范式中占据着主导地位。不过,最近人们对函数式编程的兴趣正在增长。函...
    神刀阅读 3,421评论 0 0
  • 内置对象 我们平时忙于开发,很少有时间能够将文档看一遍。这样在很多时候,我们本可以一个原生方法能够实现的程序,却累...
    汨逸阅读 2,962评论 0 0
  • arr.reduce(callback[accumulator, currentValue, currentInd...
    Time_Notes阅读 1,720评论 0 0
  • 1.new 、 delete 、 malloc 、 free 关系 delete 会调用对象的析构函数 , 和 n...
    可不期诺Cappuccino阅读 4,485评论 0 0
  • 写在前面: 犹豫了一下,不知道该不该发这么多。毕竟题目虽全,但是其实很多人看了不到一半,估计就会默默的收藏保存,等...
    Yt_cc阅读 14,963评论 1 6

友情链接更多精彩内容