Currying

2018-02-24 15:53 更新

Currying

我遇見(jiàn)的大多數(shù)碼農(nóng)都讀過(guò)“四人幫”的那本《設(shè)計(jì)模式》。任何稍有自尊心的碼農(nóng)都會(huì)說(shuō)這本書(shū)和語(yǔ)言無(wú)關(guān),因此無(wú)論你用什么編程語(yǔ)言,當(dāng)中提到的那些模式大體上適用于所有軟件工程。聽(tīng)起來(lái)很厲害,然而事實(shí)卻不是這樣。
函數(shù)式語(yǔ)言的表達(dá)能力很強(qiáng)。用這種語(yǔ)言編程的時(shí)候基本不需要設(shè)計(jì)模式,因?yàn)檫@種語(yǔ)言層次已經(jīng)足夠高,使得使用者可以以概念編程,從而完全不需要設(shè)計(jì)模式了。以適配器模式為例(有人知道這個(gè)模式和外觀模式有什么區(qū)別嗎?怎么覺(jué)得有人為了出版合同的要求而硬生生湊頁(yè)數(shù)?)(譯者:您不愧是高級(jí)黑?。?。對(duì)于一個(gè)支持currying技術(shù)的語(yǔ)言來(lái)說(shuō),這個(gè)模式就是多余的。
在Jaya中最有名的適配器模式就是在其“默認(rèn)”抽象單元中的應(yīng)用:類(lèi)。在函數(shù)式語(yǔ)言中這種模式其實(shí)就是函數(shù)。在這個(gè)模式中,一個(gè)接口被轉(zhuǎn)換成另外一個(gè)接口,讓不同的用戶(hù)代碼調(diào)用。接下來(lái)就有一個(gè)適配器模式的例子:

int pow(int i, int j);
int square(int i)
{
    return pow(i, 2);
}

上面的代碼中square函數(shù)計(jì)算一個(gè)整數(shù)的平方,這個(gè)函數(shù)的接口被轉(zhuǎn)換成計(jì)算一個(gè)整數(shù)的任意整數(shù)次冪。在學(xué)術(shù)圈里這種簡(jiǎn)單的技術(shù)就被叫做currying(因?yàn)檫壿媽W(xué)家哈斯凱爾·加里用其數(shù)學(xué)技巧將這種技術(shù)描述出來(lái),于是就以他的名字來(lái)命名了)。在一個(gè)FP語(yǔ)言中函數(shù)(而不是類(lèi))被作為參數(shù)進(jìn)行傳遞,currying常常用于轉(zhuǎn)化一個(gè)函數(shù)的接口以便于其他代碼調(diào)用。函數(shù)的接口就是它的參數(shù),于是currying通常用于減少函數(shù)參數(shù)的數(shù)量(見(jiàn)前例)。
函數(shù)式語(yǔ)言生來(lái)就支持這一技術(shù),于是沒(méi)有必要為某個(gè)函數(shù)手工創(chuàng)建另外一個(gè)函數(shù)去包裝并轉(zhuǎn)換它的接口,這些函數(shù)式語(yǔ)言已經(jīng)為你做好了。我們繼續(xù)拓展Java來(lái)支持這一功能。

square = int pow(int i, 2);

上面的語(yǔ)句實(shí)現(xiàn)了一個(gè)平方計(jì)算函數(shù),它只需要一個(gè)參數(shù)。它會(huì)繼而調(diào)用pow函數(shù)并且把第二個(gè)參數(shù)置為2。編譯過(guò)后將生成以下Java代碼:

class square_function_t {
    int square(int i) {
        return pow(i, 2);
    }
}
square_function_t square = new square_function_t();

從上面的例子可以看到,很簡(jiǎn)單的,函數(shù)pow的封裝函數(shù)就創(chuàng)建出來(lái)了。在FP語(yǔ)言中currying就這么簡(jiǎn)單:一種可以快速且簡(jiǎn)單的實(shí)現(xiàn)函數(shù)封裝的捷徑。我們可以更專(zhuān)注于自己的設(shè)計(jì),編譯器則會(huì)為你編寫(xiě)正確的代碼!什么時(shí)候使用currying呢?很簡(jiǎn)單,當(dāng)你想要用適配器模式(或是封裝函數(shù))的時(shí)候,就是用currying的時(shí)候。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)