Scala中f(a,b)和f(a)(b)之间的差异

时间:2016-08-03 14:24:10

标签: scala

我对Scala非常新。我正在阅读Paul Chiusano和RúnarBjarnason在scala中编写的一本名为函数式编程的书。到目前为止,我发现它很有趣。我看到咖喱和不发作的解决方案

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型的值但是在不合理的情况下我不理解f(a)(b)。任何人都可以告诉我如何阅读f(a)(b)或这是如何产生一种C或请参考我一些可以向我解释的在线资料?

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

基本上f(a)的返回类型是B => C类型的函数,我们可以调用此结果g。 如果您随后致电g(b),则会获得C类型的值。 f(a)(b)可以扩展为f.apply(a).apply(b)

答案 1 :(得分:2)

uncurry方法中,你采用了一个所谓的“curried”函数,这意味着你没有一个评估 n 参数的函数,而是 n 函数评估一个参数,每个参数返回一个新函数,直到你评估最后一个参数。

如果没有语言的特定支持,那么你必须做这样的事情:

// 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
然而,Scala为currying提供了进一步的支持,允许你写这个:

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

在这两种情况下,您可以部分应用curriedSum,获取一个取整数的函数,并将其与最初传入的数相加,如下所示:

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

让我们回到你的案例:正如我们所提到的,uncurry采用 curried 函数并将其转换为常规函数,这意味着

f(a)(b)

可以读作:“将参数a应用于函数f,然后获取结果函数并将参数b应用于它”。

答案 2 :(得分:2)

如果有人正在寻找解释。这link更好地解释了

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

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

curry后

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

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

在第一个示例中,add方法接受两个参数并返回添加两个参数的结果。第二个示例重新定义了add方法,这样它只需要一个Int作为参数,并返回一个函数(闭包)作为结果。然后我们的驱动程序代码调用此函数,传递第二个“参数”。此函数计算值并返回最终结果。