Scala之 柯里化(Currying)

2021-10-08 03:54:27 字數 2818 閱讀 6929

柯里化的神秘面紗

柯里化(currying)技術 christopher strachey 以邏輯學家 haskell curry 命名的(儘管它是 moses schnfinkel 和 gottlob frege 發明的)。它是把接受多個引數的函式變換成接受乙個單一引數(最初函式的第乙個引數)的函式,並且返回接受餘下的引數且返回結果的新函式的技術。

簡單理解就是改變函式的表達形式但其功能特性不變,柯里化其實是具有很高的實用性的。無論是在提高適用性還是在延遲執行或者固定易變因素等方面,柯里化技術都發揮著重要的作用。

例項:單引數列表

def add

(x: int,y: int)

= x + y

柯里化(多引數列表)

def add

(x: int)

(y: int)

= x + y

應用的時候,是這樣用:add(1)(2),最後結果都一樣是3,這種方式(過程)就叫柯里化。

解析:

add(1)(2) 實際上是依次呼叫兩個普通函式(非柯里化函式),第一次呼叫使用乙個引數 x,返回乙個函式型別的值,第二次使用引數y呼叫這個函式型別的值。

使用柯里化技術可以將上述2個整數的加法函式改修為接受乙個引數的函式,只是該函式返回是乙個以原有第二個引數為引數的函式。

def add

(x:int)

=(y:int)

=>x+y

概述:

接收乙個x為引數,返回乙個匿名函式,該匿名函式的定義是:接收乙個int型引數y,函式體為x+y。

上述使用柯里化技術得到等價新函式,在scala語言中看起來還不是很簡潔,在scala中可以進一步簡化為:

def add

(x: int)

(y: int)

= x + y

現在我們來對這個方法進行呼叫。

val result =

add(

1)

返回乙個result,那result的值應該是乙個匿名函式:(y:int)=>1+y

所以為了得到結果,我們繼續呼叫result。

val sum =

result(2

)

最後列印出來的結果就是3。

同樣對於三個整數加法的函式在scala中由於有柯里化的存在,自然有多種功能等價的函式定義形式,如以下四種函式都是實現了三個整數加法功能,只不過呼叫不同形式引數過程略有不同。

直接參入三個引數的一步到位就可以得到運算結果,而傳入1或者2個引數的需要分步驟再傳入第2/3或者第3個引數才能求出三個整數相加的結果,很好地體現了延遲執行或者固定易變因素等方面能力。

def sums

(x:int,y:int,z:int)

=x+y+z

def sum1

(x:int)

=(y:int,z:int)

=>x+y+z

def sum2

(x:int)

(y:int)

(z:int)

=x+y+z

def sum3

(x:int)

(y:int)

=(z:int)

=>x+y+z

編譯執行的結果都是一樣.

一般情況下,多引數函式定義為

def f(args1)…(argsn) = e,

當n > 1時,等同於

def f(args1)…(args n-1) =

或者def f(args1)…(args n-1) = (argsn => e)。

如果重複這個過程n次,得到

def f = (args1 => (args2 => … (argsn => e) ) )

這種函式定義稱為柯里化(currying)。

scala中柯里化的另一種典型案例——

在scala中corresponds方法能使得兩個序列按照一定的條件進行比較,該方法其實也是經過柯里化引數的。在scala的api中該方法定義如下:

在方法簽名描述中有兩個引數,that序列和p函式,其中p函式有兩個引數,第二個引數型別是與that序列一致的。

應用柯里化,我們可以省去第二個引數中b的型別,因為從that序列中推斷出b的型別。

def corresponds[b]

(that: genseq[b]

)(p:

(t, b) ⇒ boolean)

: boolean

因此假如有字串型別序列a和字串序列b,我們可以使用a. corresponds(b)(. equalsignorecase())來判斷兩個字串序列在不區分大小的情況是否一致,這就為程式設計帶來了「魔法般」的靈活性。

柯里化的作用

1、柯里化技術在提高適用性還是在延遲執行或者固定易變因素等方面有著重要重要的作用,加上scala語言本身就是推崇簡潔編碼,使得同樣功能的函式在定義與轉換的時候會更加靈活多樣。

2、在scala柯里化中,閉包也發揮著重要的作用。所謂的閉包就是變數出了函式的定義域外在其他**塊還能其作用,這樣的情況稱之為閉包。就上述討論的案例而言,如果沒有閉包作用,那麼轉換後函式其實返回的匿名函式是無法在與第乙個引數x相關結合的,自然也就無法保證其所實現的功能是跟原來一致的。

scala之柯里化

scala中可以定義乙個函式 1.柯里化,注意cookfood與cookfood1 cookfood2是同乙個方法,但是引數展示的形式被分開,這就是柯里化。def cookfood potato string,tomato string,cook string unit unit def cookf...

Scala柯里化和反柯里化

名詞解釋 在電腦科學中,柯里化 currying 是把接受多個引數的函式變換成接受乙個單一引數 最初函式的第乙個引數 的函式,並且返回接受餘下的引數且返回結果的新函式的技術。柯里化舉例說明 def curry1 a,b,c a a,f a,b c b c b b f a,b 這個函式的結果是乙個高階...

Scala 函式柯里化

柯里化指的是將原來接受多個引數的函式變成新的接受乙個引數的函式的過程,新函式的引數接受原來的第二個引數為唯一引數,如果有n個引數,就是把這個函式分解成n個新函式的過程 1 函式程式設計中,接受多個引數的函式都可以轉化為接受單個引數的函式,這個轉化過程就叫柯里化 2 柯里化就是證明了函式只需要乙個引數...