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.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357

推荐阅读更多精彩内容

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