2016-08-03 172 views
2

我對Scala非常陌生。我正在閱讀由Paul Chiusano和RúnarBjarnason編寫的scala函數式編程書。到目前爲止,我發現它很有趣。我看到咖喱和溶液uncurryScala中f(a,b)和f(a)(b)之間的區別

def curry[A,B,C](f: (A, B) => C): A => (B => C)= { 
    a => b => f(a,b) 
    } 

def uncurry[A,B,C](f: A => B => C): (A, B) => C = { 
    (a,b) => f(a)(b) 
    } 

在庫裏我明白F(A,B),這導致在類型C的值,但在uncurry我不理解F(A)(B)。任何人都可以請告訴我如何閱讀f(a)(b)或如何產生一種類型的C或請向我推薦一些可以向我解釋這一點的在線材料?

感謝您的幫助。

+1

[This](http://stackoverflow.com/documentation/scala/1636/currying/5412/currying#t=201608031429246291326)示例可能描述了兩者。 –

回答

2

基本上f(a)的返回類型是B => C類型的函數,我們稱這個結果爲g。 如果您隨後致電g(b),您將獲得類型爲C的值。 f(a)(b)可擴展到f.apply(a).apply(b)

2

uncurry方法,你需要一個所謂的「令行禁止」的功能,也就是說,不是具有評估ň參數的函數,你必須ň功能評估一個說法,每個函數都會返回一個新的函數,直到您評估爲止。

從語言沒有特定的支持討好的意思是你必須做這樣的事情:

// curriedSum is a function that takes an integer, 
// which returns a function that takes an integer 
// and returns the sum of the two 
def curriedSum(a: Int): Int => Int = 
    b => a + b 

斯卡拉但是提供了討好,讓您寫這進一步支持:

def curriedSum(a: Int)(b: Int): Int = a + b 

在在這兩種情況下,都可以部分應用curriedSum,得到一個函數,該函數需要一個整數並將其與您最初傳入的數字相加,如下所示:

val sumTwo: Int => Int = curriedSum(2) 
val four = sumTwo(2) // four equals 4 

讓我們回到你的情況:當我們提到,uncurry需要咖喱功能,並把它變成一個普通的功能,這意味着

f(a)(b) 

可以爲已讀:「應用參數a的功能f,然後取得結果函數並將參數b應用於它「。

+0

技術上'def curriedSum(a:Int)(b:Int):Int = a + b'不是一個curried函數,它是一個包含多個參數列表的方法。它主要用於類型推斷,並用於在功能上下文中將其轉換爲curried函數。只是爲了準確。 –

+0

謝謝你指出。我想Scala的OO/FP二元性仍然讓我對這門語言感到困惑。 :) – stefanobaghino

0

如果有人正在尋找解釋。此link解釋它更好

def add(x:Int, y:Int) = x + y 

add(1, 2) // 3 
add(7, 3) // 10 

討好

def add(x:Int) = (y:Int) => x + y 

add(1)(2) // 3 
add(7)(3) // 10 

在第一個樣品後,添加方法有兩個參數,並返回相加兩個的結果。第二個示例重新定義add方法,以便它只接受一個I​​nt作爲參數,並返回一個函數(閉包)。我們的驅動程序代碼然後調用這個功能,傳遞第二個「參數」。該功能計算該值並返回最終結果。

相關問題