JS|Currying

#js

2023-11-06


前言

我看到了一個面試題目

var result = add(1)(2)(3)

要怎麼實作這個 funtion 呢?

來源

柯里化(Currying)這個名稱來自於 20 世紀初期的美國數學家和邏輯學家 Haskell Curry,是計算機科學和數學領域的一位重要人物,並且對組合邏輯(Function Composition)和函數式編程(Functional Programming)有深遠的貢獻。柯里化這個名稱是為了紀念他的貢獻而命名的。

柯里化的本質是將多參數函數轉化為接受單一參數一系列嵌套函數。這種轉化有助於更容易地處理部分應用函數組合高階函數

基礎範例

以下為非 Currying 的 function

function add(x, y) {
  return x + y;
}

將其轉為 Currying function

function curriedAdd(x) {
  return function(y) {
    return x + y;
  };
}

接下來我們就可以這麼使用:

const add5 = curriedAdd(5);
console.log(add5(3)); // 8

部分應用(Partial Application)

Currying 使部分應用變得更加容易。部分應用是指只提供函數的一部分參數,然後返回一個新函數,等待提供剩餘的參數。這有助於創建更具彈性的函數,可以在需要的時候提供參數。

組合函數(Function Composition)

Currying 使函數的組合變得更加容易,這有助於構建更複雜的函數。你可以將多個柯里化的函數組合在一起,以實現更複雜的邏輯。

延遲評估(Lazy Evaluation)

Currying 的概念與延遲評估相關。延遲評估是一種只在需要時才計算結果的概念,柯里化有助於實現這種特性。

更複雜的範例

function add(x) {
  return function(y) {
    if (y === undefined) {
      return x;
    } else {
      return add(x + y);
    }
  };
}

var result = add(1)(2)(3)();
console.log(result); // 6

我理解這個的切入點是,每層都是 return 一個 已打包好 x 在裡面的 function ,每層 function 再檢查是否還有下一個輸入,沒有就會回傳最終結果 x ,有就繼續將 x + y 放入下一層遞迴中。

可以從 add(1)()add(1)(2)() 開始慢慢理解。

與 Closure 的關係

其實某方便來說 Currying 就是用 Closure 的特性,將當下的 Lexical Environment 打包在要回傳的下一個 function 裡。

重點整理

  • Currying 將 多重輸入參數 的 function 轉變成多個 單一輸入參數 連環嵌套的 function
  • Currying 利用 Closure 打包當下用到的參數給下一個 function
  • 助於 Functional Programming
  • 助於處理 Partial Application:先輸入部分參數、返回新的函數
  • 助於 Composition Programming 結合成更複雜的邏輯
  • 助於 Lazy Evaluation,只在需要時才繼續計算結果

感謝您的閱讀

這個部落格才剛成立,我仍然在調整畫面,覺得這個時代資訊都太複雜了、社群軟體的廣告又多,希望在這裡可以提供一個最舒適的閱讀體驗,讓您可以專注、最小化干擾、一同心流。


我也正在學習中,一定會有寫錯或疏漏的部分,如果有任何錯誤或是疑問,歡迎寄信給我:agwurn.dev@gmail.com

author_img

Agwurn Lu

practice makes perfect