2012-06-03 71 views
3

咖喱函數的結果是部分應用的函數嗎?雖然我理解部分功能應用程序的工作方式,但我理解如何使用currying作品,但我不清楚這些概念是否存在一些問題。咖喱會產生部分應用的功能嗎?

我的困惑來自Learn you a Haskell for great good的以下引用,這與我之前對基於this blog post by John Skeet的概念的理解相沖突。

簡單地說,如果我們調用太少參數的函數,我們得到 回到一個部分應用功能,這意味着一個函數,如 許多參數,我們離開了。

舉個例子(在F#雖然問題是關於在一般功能的編程)

> let add a b = a + b;; 

val add : int -> int -> int 

> let inc = add 1;; 

val inc : (int -> int) 

在這個例子中是inc一個部分應用功能?

+3

Downvote and no comment? –

+1

Upvote for Karma :) –

+1

這只是關於你怎麼想的。形式上,不存在「部分應用函數」這樣的事情:「inc」是一個函數;這就是「它是什麼」。我們將它看作是「部分應用的函數」,因爲它也是代表「add」的部分應用的對象。 –

回答

3

一般來說,討好手段轉化兩個參數的函數爲一個帶一個參數,並返回另一個一個參數的函數,從而使調用咖喱函數的第一個參數,然後這樣做的結果的結果第二個參數相當於使用兩個參數調用原始(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的前奏定義了兩個函數,curryuncurry這兩個表示之間轉換:curry((a,b) -> c) -> a -> b -> c類型的,即,它需要一個一個參數的函數,它接受一個元組(a, b),並返回一個c,並使它轉動轉換爲a -> b -> c類型的函數,該函數採用a並返回一個函數,該函數需要b並返回cuncurry是相反的。

部分申請並不是真正的事情;它只是一個給予您有咖喱功能的情況的名稱(例如f a b),而不是完全展開整個鏈(例如,f 23 42),您在此過程中的某個地方停下來,並進一步傳遞結果函數。 let g = f 23。爲了部分應用一個函數,它必須被curry(你不能部分地應用f (a, b)作爲let g = f (a)),但是因爲以curry方式編寫函數是Haskell中的默認函數,所以部分應用程序很容易並且很常見。

+3

實際上,您可以部分應用不安全的功能。如果'f(a,b,c)= { - ... - }',則部分應用'g(a,c)= f(a,2,c)'。一般來說,currying將'a×b→c'類型的函數轉換爲'a→(b→c)',並且部分應用程序將一個(或多個)參數:'a×b×c→d'固定爲'a×c →d'(例如)。 – Vitus

0

簡答:inc是通過部分應用獲得的功能。

curried函數的結果是目標語言(Haskell,F#或其他)中某種類型的值,因此它可能是一個函數(但它也可能是一個整數,布爾值,...,取決於你的聲明)。

關於部分應用程序...它只是給函數應用程序返回其他函數的名稱,但從技術上講,它是一個函數應用程序,與其他函數類似。這甚至不是強制性的,你返回的函數是基於前面的參數。以\x -> id爲例:您始終獲得身份識別功能,相對於輸入x獨立。