currying和部分應用有什麼區別?

我常常在互聯網上看到各類各樣的抱怨,其餘人的currying例子並非currying,但實際上只是部分應用。 html

我沒有找到關於部分應用是什麼的合理解釋,或者它與currying有何不一樣。 彷佛存在廣泛的混淆,在某些地方將等效的例子描述爲currying,在其餘地方描述爲部分應用。 編程

有人能夠向我提供這兩個術語的定義,以及它們如何區別的細節嗎? 閉包


#1樓

注意:這是從F#Basics中獲取的,這是.NET開發人員進入函數式編程的優秀介紹性文章。 app

Currying意味着將具備許多參數的函數分解爲一系列函數,每一個函數都接受一個參數並最終產生與原始函數相同的結果。 對於功能編程新手來講,Currying多是最具挑戰性的話題,特別是由於它常常與部分應用混淆。 您能夠在此示例中看到二者都在工做: 函數式編程

let multiply xy = x * y let double = multiply 2 let ten = double 5

您應該當即看到與大多數命令式語言不一樣的行爲。 第二個語句經過將一個參數傳遞給一個帶兩個的函數來建立一個名爲double的新函數。 結果是一個函數,它接受一個int參數併產生相同的輸出,就好像你已經調用了multiply,x等於2,y等於那個參數。 在行爲方面,它與此代碼相同: 函數

let double2 z = multiply 2 z

一般,人們錯誤地認爲乘法是造成雙重的。 但這只是有點真實。 乘法函數是curry,可是在定義時會發生這種狀況,由於默認狀況下F#中的函數是curry。 當建立雙重函數時,更準確地說,部分應用了乘法函數。 ui

乘法函數其實是一系列兩個函數。 第一個函數接受一個int參數並返回另外一個函數,有效地將x綁定到特定值。 此函數還接受一個int參數,您能夠將其視爲綁定到y的值。 在調用第二個函數以後,x和y都被綁定,所以結果是x和y的乘積,如double體中所定義。 spa

要建立double,將計算乘法函數鏈中的第一個函數以部分應用乘法。 結果函數的名稱爲double。 當計算double時,它使用其參數以及部分應用的值來建立結果。 code


#2樓

我在另外一個主題https://stackoverflow.com/a/12846865/1685865中回答了這個問題。 簡而言之,部分函數應用程序是關於修復給定多變量函數的一些參數以產生具備較少參數的另外一個函數,而Currying是關於將N個參數的函數轉換爲返回一元函數的一元函數... [示例在這篇文章的末尾顯示了Currying。] htm

Currying主要是理論上的興趣:人們能夠僅使用一元函數來表達計算(即每一個函數都是一元的)。 在實踐中和做爲副產品,若是語言具備curried功能,它是一種可使許多有用(但不是所有)部分功能應用程序變得微不足道的技術。 一樣,它不是實現部分應用程序的惟一方法。 所以,您可能會遇到以其餘方式完成部分應用程序的狀況,但人們將其誤認爲是Currying。

(Currying的例子)

在實踐中,人們不會只寫

lambda x: lambda y: lambda z: x + y + z

或等效的JavaScript

function (x) { return function (y){ return function (z){ return x + y + z }}}

代替

lambda x, y, z: x + y + z

爲了Currying。


#3樓

對我來講,部分應用程序必須建立一個新函數,其中使用的參數徹底集成到結果函數中。

大多數函數式語言經過返回閉包來實現currying:在部分應用時不要在lambda下求值。 所以,對於有趣的部分應用,咱們須要在currying和部分應用之間作出區別,並將部分應用視爲curda和lambda下的評估。


#4樓

經過如下JavaScript示例能夠最好地說明curry和部分應用程序之間的區別:

function f(x, y, z) {
    return x + y + z;
}

var partial = f.bind(null, 1);

6 === partial(2, 3);

部分應用致使更小的功能; 在上面的例子中, f的arity爲3,而partial只有2的arity。更重要的是,部分應用的函數會在調用時當即返回結果 ,而不是currying鏈中的另外一個函數。 所以,若是你看到像partial(2)(3)這樣的東西,它實際上不是部分應用。

進一步閱讀:


#5樓

有趣的問題。 通過一番搜索後, 「部分功能應用程序沒有進行調整」給出了我發現的最佳解釋。 我不能說實際差別對我來講特別明顯,但後來我不是FP專家......

另外一個有用的頁面(我認可我還沒有徹底閱讀)是「使用Java閉包進行Currying和部分應用程序」

看起來這看起來像是一對普遍混淆的術語,請注意。

相關文章
相關標籤/搜索