Welcome to Michael's Blog! 🎉 currently Renew and moving old post 🫠

Functional Programming Concepts - Curry、Compose、Pipe

探討函數式編程中的 Curry、Compose、Pipe 的實作與應用

Loading comments...

函數式編程(Functional Programming, FP)中,高階函數是核心概念之一。本文將探討三個重要的函數轉換技巧:Curry、Compose、Pipe,並著重分析它們在現代前端開發中的應用。

概念比較

概念主要用途執行順序實際應用
Curry參數部分應用依序傳入參數API 請求配置
Compose函數組合從右到左數學運算、資料轉換
Pipe資料流處理從左到右表單處理、API 資料流

實作與範例

Curry (柯里化)

type Curry<T extends (...args: any[]) => any> =
  T extends (arg: infer A, ...args: infer R) => infer O
    ? R extends []
      ? T
      : (arg: A) => Curry<(...args: R) => O>
    : never;

// 實際應用:API 請求配置
const fetchFromAPI = curry((baseURL: string, endpoint: string, id: string) =>
  fetch(`${baseURL}${endpoint}/${id}`)
);

const fetchFromMyAPI = fetchFromAPI('https://api.example.com');
const fetchUser = fetchFromMyAPI('/users');

Compose 與 Pipe

特性ComposePipe
執行順序從右到左 (f(g(x)))從左到右 (x → g → f)
數學概念符合數學函數組合符合資料流處理
可讀性需要從內到外閱讀符合直覺閱讀順序
適用場景數學運算、純函數組合資料處理流程、事件處理
// Compose 示例
const processData = compose(
  formatOutput, // 3. 格式化
  validateData, // 2. 驗證
  normalizeInput // 1. 標準化
);

// Pipe 示例
const processData = pipe(
  normalizeInput, // 1. 標準化
  validateData, // 2. 驗證
  formatOutput // 3. 格式化
);

工具結合

與 RxJS 的結合

// 搜尋功能實作
const searchInput$ = fromEvent<InputEvent>(searchInput, 'input').pipe(
  map(event => (event.target as HTMLInputElement).value),
  debounceTime(300),
  distinctUntilChanged(),
  switchMap(async (term) => {
    const response = await fetch(`/api/search?q=${term}`);
    return response.json();
  })
);

常見應用場景

場景推薦方案原因
表單處理Pipe + RxJS清晰的資料流、方便的異步處理
API 資料處理Pipe直觀的轉換流程
配置管理Curry靈活的參數應用
數學計算Compose符合數學直覺

選擇方向

考量面向建議選擇說明
團隊經驗Pipe最直觀、容易理解
資料處理Pipe + RxJS強大的資料流處理能力
函數組合Compose符合 functional programming 的特性
配置管理Curry靈活的參數管理

總結

在日常開發中:

  1. Pipe 因爲比較直觀所以比較常見一些
  2. 結合 RxJS 能夠處理複雜的非同步資料流
  3. Curry 和 Compose 在特定場景下也是有幫助,但需要謹慎使用,建議盡可能跟團隊有共識,避免過度使用,導致程式碼難以閱讀
Loading comments...