Scala中的Currying示例

Kev*_*ith 4 scala currying

以下是currying的一个很好的例子吗?

def sum(a: Int, b: Int) : (Int => Int) = {
    def go(a: Int) : Int = {
        a + b;
    }
    go
}
Run Code Online (Sandbox Code Playgroud)

我一半了解下面的结果,但我怎么能用sum()咖喱的方式写(或者我应该怎么写)呢?

scala> sum(3,4) res0: Int => Int = <function1>
scala> sum(3,4).apply(2) res1: Int = 6
scala> sum(3,4).apply(3) res2: Int = 7
Run Code Online (Sandbox Code Playgroud)

4le*_*x1v 7

在Scala中引入了Currying机制以支持类型推断.例如foldLeft标准库中的函数:

def foldLeft[B](z: B)(op: (B, A) => B): B
Run Code Online (Sandbox Code Playgroud)

没有currying你必须明确提供类型:

def foldLeft[B](z: B, op: (B, A) => B): B
List("").foldLeft(0, (b: Int, a: String) => a + b.length)
List("").foldLeft[Int](0, _ + _.length)
Run Code Online (Sandbox Code Playgroud)

编写curried函数有三种方法:

1)以currying形式书写:

def sum(a: Int)(b: Int) = a + b
Run Code Online (Sandbox Code Playgroud)

这只是语法糖:

def sum(a: Int): Int => Int = b => a + b
Run Code Online (Sandbox Code Playgroud)

2)调用curried函数对象(sum _).curried并检查类型:

sum: (a: Int, b: Int)Int
res10: Int => (Int => Int) = <function1>
Run Code Online (Sandbox Code Playgroud)

在您的示例中,您可以使用Scala类型推断来减少代码量并更改代码:

def sum(a: Int, b: Int) : (Int => Int) = {
    def go(a: Int) : Int = {
        a + b;
    }
    go
}
Run Code Online (Sandbox Code Playgroud)

成:

def sum(a: Int, b: Int) : (Int => Int) = c => a + b + c
Run Code Online (Sandbox Code Playgroud)

在语义上这些是相同的,因为你明确提供了返回类型,因此Scala知道你将返回一个函数,它接受一个Int参数并返回一个Int

也谈curring一个更完整的答案给出的返璞词

  • 严格来说`def sum_1(a:Int)(b:Int)= a + b`不是`def sum_2(a:Int):Int =&gt; Int = b =&gt; a + b`的语法糖调用`sum_2(1)`,但我不能调用`sum_1(1)`(我必须调用`sum_1(1)_`)。sum_1不被认为是单参数方法,与currying概念矛盾。 (2认同)