柯里化
定義
在電腦科學中,柯里化(英語:Currying),是把接受多個引數的函式變換成接受一個單一引數(最初函式的第一個引數)的函式,並且返回接受餘下的引數而且返回結果的新函式的技術。
就是把 foo(x, y, z)
變成 foo(x)(y)(z)
為什麼需要柯里化
柯里化是一種程式設計的模式,並不是說某些功能只能用柯里化才能實現,而是說在一定的場景下使用柯里化使程式碼更加簡潔、程式碼複用度更高。
我們以“比較兩個數”的例子來說明。
方案一
程式碼如下:
判斷 1 是否大於 10 compare(1, 10, greaterThan)
我們有判斷是否大於 10 的需求,並且需要呼叫 n 次
compare(1, 10, greaterThan)
compare(2, 10, greaterThan)
compare(3, 10, greaterThan)
......
這裡的引數 10、greaterThan 是重複程式碼的,我們優化一下。
方案二
function greaterThan10(value) {
return compare(value, 10, greaterThan);
}
greaterThan10(1);
greaterThan10(2);
greaterThan10(3);
......
然後我們又有需求,判斷是否大於 11 且需要呼叫 n 次,按這種思路需要不斷寫 greaterThan*
方法,這是換了一種形式來寫重複程式碼,方案一與方案二沒有本質區別。
有沒有更簡潔的方式?答案是使用柯里化。
方案三
注意:這裡用的是 curry2 只支援兩個引數。
然後我的程式碼變為:
const greaterThan10 = greaterThan(10);
greaterThan10(1);
greaterThan10(2);
greaterThan10(3);
......
const greaterThan11 = greaterThan(11);
greaterThan11(1);
greaterThan11(2);
greaterThan11(3);
......
而且我們還能輕鬆實現判斷是否小於某數的功能,程式碼如下:
const lessThan10 = lessThan(10);
lessThan10(1);
lessThan10(2);
lessThan10(3);
......
lessThan(11)(1);
最後我們來對比下,看看使用柯里化的效果
方案一:
compare(1, 10, greaterThan);
compare(2, 10, greaterThan);
compare(3, 10, greaterThan);
......
方案三:
const greaterThan10 = greaterThan(10);
greaterThan10(1);
greaterThan10(2);
greaterThan10(3);
......
不使用柯里化時,三個引數為一個粒度;柯里化可以把三個引數分成三個粒度,在更細的粒度上實現程式碼的複用,複用度更高。
如何使用柯里化
上文中提到的 curry2 只支援兩個引數的情況,如果有更多的引數,不可能一直寫 curry3....n,可以使用 Lodash curry,支援任意引數個數。
注意 Lodash curry 方法不僅支援任意引數個數,還支援“部分應用”。
函數語言程式設計也經常看到部分應用,可以把部分應用理解成高階的柯里化,即 foo(x, y, z)
變成 foo(x)(y)(z)
、foo(x, y)(z)
、foo(x)(y, z)
Promise 柯里化
對於非同步的場景經常會出現如下程式碼:
成功的回撥和 catch 常常會有程式碼重複,能不能把這部分的邏輯統一處理,並且可以輕易擴充套件,允許定製化需求。
柯里化主要思想是高階函式的應用,在提供部分引數時返回一個新的函式,供其他引數繼續呼叫。根據柯里化的主要思想實現 Promise 的柯里化 pcurry 庫(傳統的柯里化方法並不適用非同步的情況)。
程式碼如下:
即支援統一的錯誤處理 decorate1,也可以定製化過濾器 decorate2,decorate2 複用了 decorate1 的邏輯。
pcurry 在接收一個函式引數時返回一個函式,並把函式新增到一個佇列 flow,在接收一個 promise 物件時按順序呼叫函式佇列 flow。
相關文章
- 柯里化與反柯里化
- 理解柯里化
- JavaScript柯里化JavaScript
- 高階函式應用 —— 柯里化與反柯里化函式
- 函式柯里化函式
- Js函式柯里化JS函式
- JavaScript函式柯里化JavaScript函式
- JS:函式柯里化JS函式
- Javascript currying柯里化詳解JavaScript
- 「譯」理解JavaScript的柯里化JavaScript
- 【譯】理解JavaScript中的柯里化JavaScript
- 函式的合成與柯里化函式
- 前端之函式柯里化Currying前端函式
- JavaScript函式柯里化詳解JavaScript函式
- JavaScript函式柯里化的作用JavaScript函式
- js柯里化函式的好處JS函式
- [譯] JavaScript中的函式柯里化JavaScript函式
- [譯] 柯里化與函式組合函式
- JavaScript進階之函式柯里化JavaScript函式
- JS 分步實現柯里化函式JS函式
- JS專題之函式柯里化JS函式
- 一道柯里化面試題面試題
- JS中的 偏函式 和 柯里化JS函式
- 用大白話介紹柯里化函式函式
- Ramda.js中的柯里化實現JS
- 大佬,JavaScript 柯里化,瞭解一下?JavaScript
- JS高階函式-函式柯里化JS函式
- 前端戰五渣學JavaScript——函式柯里化前端JavaScript函式
- 「前端進階」徹底弄懂函式柯里化前端函式
- 手寫系列:call、apply、bind、函式柯里化APP函式
- JavaScript 函數語言程式設計---柯里化JavaScript函數程式設計
- 函式柯里化和偏函式應用函式
- 深入理解javascript系列(十七):函式柯里化JavaScript函式
- 深入 call、apply、bind、箭頭函式以及柯里化APP函式
- 到底JS柯里化在專案中怎麼用?JS
- 一段柯里化函式程式碼閱讀函式
- 三行程式碼實現 JS 柯里化行程JS
- js函數語言程式設計(二)-柯里化JS函數程式設計