Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

curried function related questions in Scala

Tags:

scala

I have several questions related curried function. Here I ask them one-by-one

1) http://twitter.github.com/scala_school/basics.html gives an example of curried function -- I thought it's a function definition, but actually it's not. The REPL does not recognize this as a valid statement at all.

multiplyThenFilter { m: Int =>   m * 2 } { n: Int =>   n < 5}

2) Why can't we define a function from partially parameterized method? i.e., what's wrong with the following definition?

scala> def multiply(m: Int, n: Int): Int = m * n
multiply: (m: Int, n: Int)Int

scala> val timesTwo = multiply(2,_)
<console>:11: error: missing parameter type for expanded function ((x$1) => multiply(2, x$1))
       val timesTwo = multiply(2,_)
                                 ^

3) Why can't we make a partially parameterized function curried? i.e., what's wrong with the following definition?

scala> (multiply(_,_)).curried
  res13: Int => (Int => Int) = <function1>  // THIS IS OK

scala> (multiply(20,_)).curried
<console>:12: error: missing parameter type for expanded function ((x$1) => multiply(20, x$1))
              (multiply(20,_)).curried
                           ^
like image 778
chen Avatar asked Jun 10 '12 18:06

chen


People also ask

What is the use of currying functions in Scala?

Currying is the process of converting a function with multiple arguments into a sequence of functions that take one argument. Each function returns another function that consumes the following argument.

Are curried functions closures?

Curried functions are also an important application of closure. They split a function with many parameters into functions with only one parameter each. The context between function calls is saved thanks to closures (outer-inner pattern).

What is a currying function explain with an example?

Currying is when you break down a function that takes multiple arguments into a series of functions that each take only one argument. Here's an example in JavaScript: function add (a, b) { return a + b; } add(3, 4); // returns 7. This is a function that takes two arguments, a and b, and returns their sum.

How do you call a currying function?

Now, currying a function is forcing it to take a single parameter at a time. So rather than calling it like distance( start, end ) , we would call it like this: distance(start)(end) . Each parameter is passed in individually, and each function call returns another function, until all parameters have been provided.


1 Answers

Question 1

The Scala School example is confusing—it's definitely not a definition. There's an issue open for it on GitHub, so maybe it's a bug. You can imagine a reasonable definition might look like this:

def multiplyThenFilter(f: Int => Int)(p: Int => Boolean): Int => Option[Int] = {
  i =>
    val j = f(i)
    if (p(j)) Some(j) else None
}

(Or, equivalently, f andThen (Some(_) filter p).)

Then the example would be a function that doubles its input and returns the result in a Some if it's less than 5, and a None otherwise. But nobody knows exactly what the author intended until there's a response to that issue.


Question 2

The reason that your timesTwo doesn't work is just that the Scala compiler doesn't support that kind of type inference—see this question and my answer there for a bit of related detail. You'll need to go with one of the following:

def multiply(m: Int, n: Int): Int = m * n    
val timesTwo = multiply(2, _: Int)

def multiply(m: Int)(n: Int): Int = m * n    
val timesTwo = multiply(2) _

I.e., if you want type inference here you'll need to use multiple parameter lists. Otherwise you have to help the compiler out with the type.


Question 3

For your third question, assume we've got the following to avoid the issue in your second question:

val timesTwo = multiply(2, _: Int)

This is a Function1, which just doesn't have a curried method—you need a Function2 (or Function3, etc.) for that.

It just doesn't make sense to talk about currying a function with a single argument. Currying takes a function with multiple arguments and gives you a function taking a single argument that returns another function (which itself possibly takes a single argument and returns another function, etc.).

like image 147
Travis Brown Avatar answered Oct 14 '22 05:10

Travis Brown