一般來說,討好手段轉化兩個參數的函數爲一個帶一個參數,並返回另一個一個參數的函數,從而使調用咖喱函數的第一個參數,然後這樣做的結果的結果第二個參數相當於使用兩個參數調用原始(uncurried)函數。在閉包和動態類型(或類型推斷)僞C語言,這會看起來像這樣:
// The original, uncurried function:
function f(a, b) { return 2 * a - b; }
// The curried function:
function g(a) {
return function(b) {
return f(a, b);
}
}
// Now we can either call f directly:
printf("%i\n", f(23, 42));
// Or we can call the curried function g with one parameter, and then call the result
// with another:
printf("%i\n", (g(23))(42));
通過討好多次,我們可以減少任何多參數函數嵌套組的一個 - 參數功能。
在Haskell中,所有函數都是單參數;在我們的虛構C-closure-closures中,像f a b c
這樣的構造實際上相當於((f(a))(b))(c)
。真正將多個參數傳遞給一個函數的唯一方法是通過元組,例如, f (a, b, c)
- 但由於curried函數的語法比較簡單,而且語義更靈活,所以很少使用此選項。
Haskell的前奏定義了兩個函數,curry
和uncurry
這兩個表示之間轉換:curry
是((a,b) -> c) -> a -> b -> c
類型的,即,它需要一個一個參數的函數,它接受一個元組(a, b)
,並返回一個c
,並使它轉動轉換爲a -> b -> c
類型的函數,該函數採用a
並返回一個函數,該函數需要b
並返回c
。uncurry
是相反的。
部分申請並不是真正的事情;它只是一個給予您有咖喱功能的情況的名稱(例如f a b
),而不是完全展開整個鏈(例如,f 23 42
),您在此過程中的某個地方停下來,並進一步傳遞結果函數。 let g = f 23
。爲了部分應用一個函數,它必須被curry(你不能部分地應用f (a, b)
作爲let g = f (a)
),但是因爲以curry方式編寫函數是Haskell中的默認函數,所以部分應用程序很容易並且很常見。
Downvote and no comment? –
Upvote for Karma :) –
這只是關於你怎麼想的。形式上,不存在「部分應用函數」這樣的事情:「inc」是一個函數;這就是「它是什麼」。我們將它看作是「部分應用的函數」,因爲它也是代表「add」的部分應用的對象。 –