0

w.r.t Currying in scala, partly I understood below sample code.

  def product1(f:Int => Int )(a:Int, b:Int):Int = {
        println()
        if(a > b ) 1
        else
        f(a) * product1(f)(a+1, b)
      }

 product(x => x * x) (3, 4)

Out of it., I am bit confused with

product1(f)

in

product1(f)(a+1, b)

Just need explanation, what goes on here.... :( and how to pronounce verbally while explaining...

Thanks in advance..

BalaB
  • 3,687
  • 9
  • 36
  • 58

3 Answers3

3

product1 has two parameter lists. product1(f) is the application of f which is a function of kind Int => Int. If you were only to call product1(f) like so:

product1(f)

without the second parameter list, you'd get a so-called partially-applied function, i.e. a function which doesn't have all of its parameters bound (you'd still need to provide it with a and b)

Manuel Bernhardt
  • 3,135
  • 2
  • 29
  • 36
0

Look at the parameter declaration:

f:Int => Int

f is a function that maps an Int to an Int -- it takes an Int as an argument and returns an Int. An example is given:

x => x * x

returns the square of its argument.

product1(x => x * x) (3, 4)

returns the product of f(3) .. f(4) = 3*3 * 4*4

BTW, this isn't really an example of currying, since all the arguments are given. Currying would be something like

val prodSquare = product1(x => x * x)

Then,

prodSquare(1, 5)

yields 1*1 * 2*2 * 3*3 * 4*4 * 5*5

Jim Balter
  • 16,163
  • 3
  • 43
  • 66
0

For most idiomatic purposes I've seen, you may as well think of your function as having just one parameter list. Multiple parameter lists are used mostly for type inference purposes in generic functions, since type inference is done one parameter list at a time, rather than using Hindley-Milner/Algorithm W to infer the type of everything at once. Some other language features work on individual parameter lists, such as implicit parameters and implicit use of braces in place of parentheses for single-parameter parameter lists, etc.

Functions with multiple parameter lists are called in a similar way to a curried functions from a syntactic perspective, but by default, the intermediate functions aren't created. In fully curried style, each function takes only at most one argument and returns one result (which might happen to be another function, which expects on argument, and so forth). Technically, currying the function would be:

def product2(f: Int => Int): Int => Int => Int = {
  a: Int => {
    b: Int => {  
      if(a > b ) 1
      else f(a) * product2(f)(a+1)(b)
    }
  }
}

For completeness, you can treat a function with multiple parameter lists as a curried function by using an underscore after a complete parameter list. In your original example, you'd do product1(f)_, which would return a function of type (Int, Int) => Int.

In researching this question, I came upon another SO question worth checking out to understand this aspect of the language better.

Community
  • 1
  • 1
acjay
  • 34,571
  • 6
  • 57
  • 100