將多參數函數轉換為單參數函數鏈:f(a,b,c) → f(a)(b)(c)。C++ std::bind、bind1st、bind2nd 即實現此思想的工具。
void mult(int& a, int b) { a += b; cout << a << ' ' << b << endl; }
vector v(10); iota(v.begin(), v.end(), 0);
// bind 相當於 bind2nd:固定第二參數
for_each(v.begin(), v.end(), bind(mult, _1, 10)); // 每個元素 +10
// bind 相當於 bind1st:固定第一參數
for_each(v.begin(), v.end(), bind(mult, 100, _1)); // 100 + 元素
auto func = [](int x, string y){ return to_string(x) + y; };
auto f1 = bind(func, 1, _1); // f1(s) = func(1, s)
auto f2 = bind(func, _1, "xx"); // f2(i) = func(i, "xx")
auto f3 = bind(func, 3, "xxx"); // f3() = "3xxx"
auto f4 = bind(func, _2, _1); // f4(s, i) = func(i, s) 參數交換
cout << f1("x") << f2(2) << f3() << f4("xxxx", 4); // 1x 2xx 3xxx 4xxxx
F# 原生支援柯裡化:
let func x y = x.ToString() + y let f1 x = func 1 x let f2 x = func x "xx" let f3 = func 3 "xxx" let f4 x y = func y x
C# 模擬二參數綁定:
public static class BindHelper {
public static Func Bind(Func f, T2 t2)
=> t1 => f(t1, t2); // 固定第二參數
public static Func Bind(Func f, T1 t1)
=> t2 => f(t1, t2); // 固定第一參數
public static Func Bind(Func f, T1 t1, T2 t2)
=> () => f(t1, t2); // 全部固定
public static Func Bind(Func f)
=> (t2, t1) => f(t1, t2); // 交換參數
}
_1, _2... 來自 std::placeholders,表示調用時第幾個實參。std::function 或可調用對象,支援拷貝存儲。bind 是 C++ 實現部分應用與參數重排的標準工具,配合 lambda 幾乎可替代所有手寫適配器。理解柯裡化有助於函數式編程思維。