Currying syntax in scala

折月煮酒 提交于 2019-12-20 03:11:40

问题


The syntax of currying in scala is for example

def f(x: Int, b: Int) = x + y

is

def f(x: Int)(b: Int) = x + y

And currying for sum to sum for given range a and b is

  def sum(f: Int => Int, a: Int, b: Int) = {
    ...
  }

  sum(x=>x, 3, 6)          // outcome is 18 (3+4+5+6)

is

  def sum(f: Int => Int): (Int, Int) => Int = {
        def sumF(a: Int, b: Int): Int =
          if (a > b) 0
          else f(a) + sumF(a + 1, b)
        sumF
  }

  sum(x=>x)(3, 6)          // outcome is 18 (3+4+5+6)

But I don't understand why colon(:) exists between (f: Int => Int) and (Int, Int)

in def sum(f: Int => Int): (Int, Int) => Int = {

instead of

def sum(f: Int => Int)(Int, Int) => Int = {


回答1:


Your sum example is not curried. If you wanted it curried you'd do something like:

def sum(f: Int => Int)(a: Int, b: Int): Int =
    if (a > b) 0
    else f(a) + sum(f)(a + 1, b)

sum(x=>x)(3, 6)  // res0: Int = 18

Your code defines a method that takes a single argument, def sum(f: Int => Int). That argument is a function that takes and Int and returns an Int. So no currying involved.

This sum method returns a function, : (Int, Int) => Int. This returned function takes 2 Ints and returns and Int. Invoking this sum method looks like currying, but it's not.

sum(x=>x)(3, 6)

Instead you are invoking sum() with a single argument (x=>x) and then invoking the returned function with two arguments (3,6).




回答2:


(Int, Int) => Int between : and = specify the function's return type, i.e, it says sum will return another method of signature (Int, Int) => Int which takes two Int and returns another Int, and this is the signature of your inner sumF function:

You can rewrite this to the currying syntax as follows:

def sum(f: Int => Int)(a: Int, b: Int): Int = {
    def sumF(a: Int, b: Int): Int =
        if (a > b) 0
        else f(a) + sumF(a + 1, b)

    sumF(a, b)
}

This will more or less do the same thing as the method defined in OP:

sum(x => x)(3, 6)
// res11: Int = 18

But these two definitions are not exactly the same, for instance, for the currying syntax defined here, if you want to generate a new method from it, you have to specify the variable type, like:

val mysum: (Int, Int)=> Int = sum(x => x)

But for the one in OP, it can be simply val mysum = sum(x => x) as the return type of sum as already been specified.



来源:https://stackoverflow.com/questions/42350380/currying-syntax-in-scala

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!