函式是一等公民

Higher-Order Function(HOF)的前提是:語言裡的函式是一等公民(first-class citizen)——可以被賦值給變數、當參數傳、當返回值返回。JavaScript、Python、Go、Kotlin 都支援。

// 函式賦值給變數
const double = (x) => x * 2;
 
// 函式當參數(HOF)
function applyTwice(f, x) {
    return f(f(x));
}
applyTwice(double, 3);  // 12
 
// 函式當返回值(closure)
function multiplier(factor) {
    return (x) => x * factor;  // 返回一個函式
}
const triple = multiplier(3);
triple(5);  // 15

map / filter / reduce

陣列操作的三個基本 HOF,幾乎每個應用都在用:

orders = [
    {"product": "Laptop", "price": 1200, "category": "Electronics"},
    {"product": "Book", "price": 25, "category": "Education"},
    {"product": "Phone", "price": 800, "category": "Electronics"},
]
 
# filter:篩選電子產品
electronics = filter(lambda o: o["category"] == "Electronics", orders)
 
# map:提取價格
prices = map(lambda o: o["price"], electronics)
 
# reduce:加總
from functools import reduce
total = reduce(lambda acc, price: acc + price, prices, 0)
 
# 用 method chaining 更清楚(List comprehension 版)
total = sum(
    o["price"]
    for o in orders
    if o["category"] == "Electronics"
)

Curry 和 Partial Application

Curry:把接受多個參數的函式,轉成一系列接受一個參數的函式。

// 普通函式
const add = (a, b) => a + b;
 
// Curried 版本
const curriedAdd = (a) => (b) => a + b;
 
const add5 = curriedAdd(5);   // 固定第一個參數
add5(3);  // 8
add5(10); // 15

Partial Application:固定部分參數,返回一個需要剩餘參數的函式。

from functools import partial
 
def multiply(a, b):
    return a * b
 
double = partial(multiply, 2)  # 固定 a=2
double(5)   # 10
double(10)  # 20

函式組合(Function Composition)

把多個小函式串起來,輸出到下一個輸入:

const compose = (...fns) => (x) => fns.reduceRight((acc, fn) => fn(acc), x);
 
const trim = (s) => s.trim();
const toLowerCase = (s) => s.toLowerCase();
const addPrefix = (s) => `user:${s}`;
 
const normalizeUsername = compose(addPrefix, toLowerCase, trim);
normalizeUsername("  ALICE  ");  // "user:alice"

這是 Unix pipe 的函式版:trim | toLowerCase | addPrefix


和 GoF Pattern 的連接

Strategy Pattern 在物件導向裡是「把算法封裝成物件」。在函數式裡,直接傳函式就達到同樣的效果——不需要建一個 SortStrategy interface 和 QuickSortStrategy class,直接 sort(array, (a, b) => a - b)

HOF 讓很多 GoF Pattern 在函數式語言裡變成「直接傳函式」的慣用法,而不是複雜的類別階層。