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
^
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:
(Or, equivalently,
f andThen (Some(_) filter p).)Then the example would be a function that doubles its input and returns the result in a
Someif it’s less than 5, and aNoneotherwise. But nobody knows exactly what the author intended until there’s a response to that issue.Question 2
The reason that your
timesTwodoesn’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: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:
This is a
Function1, which just doesn’t have acurriedmethod—you need aFunction2(orFunction3, 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.).