2016-08-03 173 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作为参数,并返回一个函数(闭包)。我们的驱动程序代码然后调用这个功能,传递第二个“参数”。该功能计算该值并返回最终结果。

相关问题