萬物皆可柯裡化的Ramda.js及傳參詳解
引言
我們前段時間寫過好幾篇關於 RxJS 的文章,RxJS api 操作符理解起來確實比較復雜,RxJS 是函數式編程中的 lodash 庫,它消除瞭“時序”而帶來的困擾,它核心思想是:函數式 + 響應式。
本篇, 要講的不是 RxJS,而是另外一個函數式編程庫 Ramda.js ,它同樣也可以與 loadsh 對比理解,不過它的設計思路又不同瞭,它最大的特點是:所有函數都可以柯裡化傳參!以此來踐行函數式編程思想。
往下看,後面我們就能明白:Ramda 所有 Api 都能柯裡化的意義所在。
Function first,Data last
在 lodash 中,我們是這樣寫的,
var square = n => n * n; _.map([4, 8], square)
參數在前,執行函數在後。
而在 Ramda 中,強調:函數在前,參數在後。
這樣做有什麼好處呢?
就是為瞭更好實現:柯裡化。柯裡化隻需要參數一個一個的在後追加
var R = require('ramda'); R.map(square, [4, 8]) // 等同於 var R = require('ramda'); R.map(square)([4, 8])
再舉個栗子:
var R = require('ramda'); const odd = x => x%2 === 1 const data = [3, 5, 6]; R.filter(odd, data); // [3, 5] // 等同於 R.filter(odd)(data); // [3, 5] // 也可以延遲調用 const filter1 = R.filter(odd); // filter1 等待參數的傳入 // 後續再傳入 data const filter2 = filter1(data)
如果不借用 Ramda.js , 需要自行實現柯裡化,就會顯得麻煩:
const _curry = f => a => b => f(a, b) const odd = x => x%2 === 1 const _filter = _curry( (fn, arr) => arr.filter(fn) ); _filter(odd)([3,5,6]) // [3, 5]
Ramda 非常強調:R.api(fn, data)
這樣的范式;
API
來看看 Ramda 有哪些神奇的、好用的、常用的 API~
- map
map 讓每個成員依次執行通過某個函數;
const double = x => x * 2; R.map(double, [1, 2, 3]); //=> [2, 4, 6] R.map(double, {x: 1, y: 2, z: 3}); //=> {x: 2, y: 4, z: 6}
- filter
用於過濾;
const isEven = n => n % 2 === 0; R.filter(isEven, [1, 2, 3, 4]); //=> [2, 4] R.filter(isEven, {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, d: 4}
- add
求和;
R.add(2, 3); //=> 5 R.add(7)(10); //=> 17
- multiply
求積;
R.multiply(2)(5) // 10
- compose
函數組合,從右到左;
R.compose(Math.abs, R.add(1), R.multiply(2))(-4) // |-4*2 + 1|,等於 7
- pipe
函數組合,從左到右;
var negative = x => -1 * x; var increaseOne = x => x + 1; var f = R.pipe(Math.pow, negative, increaseOne)(3,4); // -(3^4) + 1 ,等於 -80
- curry
將多個參數轉換為單個參數
const addFourNumbers = (a, b, c, d) => a + b + c + d; const curriedAddFourNumbers = R.curry(addFourNumbers); curriedAddFourNumbers(1, 2)(3)(4)
Ramda 還有其它豐富的 api,也可以結合 compose/pipe 自定義特定功能函數,用這些方法來簡化程序,讓代碼變成函數式風格;
以上的例子都可在 jsrun.net/DTNKp/edit 可以在線運行測試;
更多 Ramda api 可見文檔:ramda.cn/
以上就是萬物皆可柯裡化的Ramda.js詳解的詳細內容,更多關於柯裡化Ramda.js的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- javascript函數式編程基礎
- 詳解JS中的compose函數和pipe函數用法
- Rxjs map, mergeMap 和 switchMap 的區別與聯系
- React 中使用 RxJS 優化數據流的處理方案
- JavaScript中rxjs與 Observable 兩大類操作符解析