如何自行實作 compose() 與 pipe() ?

栏目: JavaScript · 发布时间: 6年前

内容简介:VS Code 1.35.1Quokka 1.0.227

compose()pipe() 是 FP 最重要兩個 Function,其中 Function Composition 就是由這兩個 Function 展開,實務上都是直接使用 Ramda 或 Crocks 所提供的 compose()pipe() ,能自己使用 ECMAScript 實現嗎 ?

Version

VS Code 1.35.1

Quokka 1.0.227

Ramda 0.26.1

Ramda

import { compose, filter, map } from 'ramda';

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'RxJS in Action', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
];

// fn :: Number -> [a] -> [b]
let fn = price => compose(
  map(x => x.title),
  filter(x => x.price === price),
);

fn(300)(data); // ?

在Ramd 初體驗 一文中,曾經使用 Ramda 最具代表性的 compose()filter()map() 實現 function composition。

其中 compose() 為 Ramda 所提供。

如何自行實作 compose() 與 pipe() ?

compose()

import { filter, map } from 'ramda';

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'RxJS in Action', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
];

// compose :: ((y → z), (x → y), …, (o → p), ((a, b, …, n) → o)) → ((a, b, …, n) → z)
let compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));

// fn :: Number -> [a] -> [b]
let fn = price => compose(
  map(x => x.title),
  filter(x => x.price === price),
);

fn(300)(data); // ?

第 1 行

import { filter, map } from 'ramda';

沒使用 Ramda 所提供的 compose()

第 9 行

// compose :: ((y → z), (x → y), …, (o → p), ((a, b, …, n) → o)) → ((a, b, …, n) → z)
let compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));

自行使用 ECMAScript 內建的 reduce() 實現 compose()

(...fns)

使用 ES6 的 rest parameter,表示 compose() 的 argument 個數無限,且 fns 為 array,因此可大膽使用 Array.prototype 下的 method。

(f, g) => (...args) => f(g(...args))

g 為目前 function, f 為組合後 function,因為結果仍是 function,所以為 (...args) => f(g(...args))

reduce() 為 array 的 由左至右 ,因此最後 element 為 g ,相當於 compose()由右至左 運算。

如何自行實作 compose() 與 pipe() ?

pipe()

import { filter, map } from 'ramda';

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'RxJS in Action', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
];

// pipe :: (((a, b, …, n) → o), (o → p), …, (x → y), (y → z)) → ((a, b, …, n) → z)
let pipe = (...fns) => fns.reduceRight((f, g) => (...args) => f(g(...args)));

let fn = price => pipe(
  filter(x => x.price === price),
  map(x => x.title),
);

fn(300)(data); // ?

第 1 行

import { filter, map } from 'ramda';

沒使用 Ramda 所提供的 pipe()

第 9 行

// (((a, b, …, n) → o), (o → p), …, (x → y), (y → z)) → ((a, b, …, n) → z)
let pipe = (...fns) => fns.reduceRight((f, g) => (...args) => f(g(...args)));

pipe()由左至右 運算,也就是 array 的 由右至左 ,因此使用 reduceRight()

如何自行實作 compose() 與 pipe() ?

Conclusion

  • compose()pipe() 一直被認為是黑魔法,事實上只是將 function 加以 reduce() 而已,能自己寫過一次,就不會覺得那麼遙不可及了

以上所述就是小编给大家介绍的《如何自行實作 compose() 與 pipe() ?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

社群运营的艺术

社群运营的艺术

查尔斯·沃格 / 靳婷婷 / 华夏出版社 / 2017-7 / 42

社群存续的秘密,长期以来只有少数人知道,比如佛陀、耶稣及其弟子。 回溯3000年社群史,《社群运营的艺术》作者查尔斯•沃格总结了有归属感社群的七大原则。 在前互联网时代,七原则曾经造就伟大社群。在人人互联时代,应用七原则的社群将更繁荣。 本书作者耶鲁大学神学硕士查尔斯•沃格研究人类社会3000年的历史,结合个人亲身操作经历,提出了七条历经时间考验的原则:界限原则、入会原则、仪式原......一起来看看 《社群运营的艺术》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换