Currying是甚麼

鴉片不是鴨子的切片,Currying也是不是咖哩,其名稱源於其發明者Haskell Curry

它是一種functional programming(函式程式設計)的概念。會將一個接受多個參數的函式拆成多個只接受一個參數的函式,概念和partial類似,差別在partial可以接受複數個參數


使用

Currying很適合用在傳遞相同的參數給同個函式時,因為它利用閉包記憶函式建立時的環境的特性來讓程式碼更簡潔

未Curried

const isMoneyEnough = (passiveRes, negativeRes, budget, price) => {
    return budget >= price ? passiveRes : negativeRes;
};

isMoneyEnough('enough', 'not enough', 200, 105);
isMoneyEnough('enough', 'not enough', 200, 1000);
isMoneyEnough('enough', 'not enough', 200, 200);

Curried後

const isMoneyEnough = (passiveRes, negativeRes) => {
    return (price) => {
        return (budget) => {
            return budget >= price? passiveRes : negativeRes;
        }
    }
}

// 也可簡化成這樣
// const isMoneyEnough = (passiveRes, negativeRes) => price => budget => budget >= price ? passiveRes : negativeRes;

const isMoneyEnough = isMoneyEnough('enough', 'not enough')(200);

isMoneyEnough(105);
isMoneyEnough(1000);
isMoneyEnough(200);


進階使用

function curry(func) {
  return function curried(...args) {
        // 如果傳入的參數數量不小於傳入的函式接收的參數長度

        if (args.length >= func.length) { 
            // 使用apply讓curried能用傳進來的函式的功能
            return func.apply(this, args);

        } else {
            return function(...args2) { 
                // 使用apply讓這個函式能用curried的功能

                // 這樣是因為參數的數量小於傳入函式接收的參數長度時
                // 如果直接func.apply(this, args)會報錯
                // 所以才用類似遞迴的方式
                // 一次一次把參數連接起來到長度足夠才會進入if並執行

                return curried.apply(this, args.concat(args2)); 
            }
        }
  };
}

function sum(a, b, c) {
    return a + b + c;
}

let curriedSum = curry(sum);

curriedSum(1, 2, 3); // 直接進去if 
curriedSum(1, 2)(3); // 先進去else,此時args為[1, 2]。傳3進去後concat得到[1, 2, 3],進去if
curriedSum(1)(2)(3); // 先進去else,此時args為[1]。傳2進去concat得到[1, 2],再進去else。傳3進去後concat得到[1, 2, 3],進去if

currying優點

  • 將程式碼依功能拆解成更小單元,有助於重複利用
  • 利用閉包特性來讓程式碼更簡潔,達到DRY
  • 函式參數越多處理時會更加複雜。而curried function一次處理一個參數提高程式的彈性、可讀性

參考資料

Currying
Understanding JavaScript currying


#currying #curried function #Functional Programming







Related Posts

interface & 與type的比較

interface & 與type的比較

[AI人工智能] 二、安裝python虛擬環境 + pytorch

[AI人工智能] 二、安裝python虛擬環境 + pytorch

JS Advanced --Closure 閉包

JS Advanced --Closure 閉包


Comments