In the following code:
def product(f: Int => Int)(a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f)(a + 1, b)
The parameters a and b are passed to the inner function, but you could write exactly the same function definition like so:
def product(f: Int => Int, a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f, a + 1, b)
So what is the purpose of separating the parameters? In other words, why do this:
(f: Int => Int)(a:Int, b:Int)
when you can more clearly write:
(f: Int => Int, a:Int, b:Int)
Another feature of multiple parameters lists is partial application:
def sum3(a: Int)(b: Int)(c: Int): Int = a + b + c
val g: Int => Int => Int = sum3(10) _
val h: Int => Int = g(20)
val r: Int = h(30) // 10 + 20 + 30 = 60
You can partially apply a function and obtain another function which is equivalent to the original one but with one of the arguments fixed. _ after sum3(10) is needed because sum3 is a method, not a function, and _ converts methods to functions.
This is very useful when you are using higher-order functions:
def adder(x: Int)(y: Int) = x + y
Seq(1, 2, 3, 4) map adder(10) // Seq(11, 12, 13, 14)
When partially applied method/function is used as an argument of a higher-order call, _ is not needed, and the syntax becomes very succinct.
Another use case of this feature is that if you want to create a control structure that looks like it's built into Scala programming language itself.
For example, I could write an control structure named times which help me execute the code block exactly n times by the following method definition:
// since block is call by name, it will not be evaluate when you call it.
def times(n: Int)(block: => Any): Unit = {
for (i <- 0 until n) {
block // evaluate(execute) block
}
}
// Now I can use the times method like a control structure
times(5) {
println("Hello World");
}
It depends whether there is implicit parameter (which can't be properly mixed with plain ones)...
def foo(i: Int)(implicit p: P): Foo
... and the way you want to call it ...
def foo1(a: Int)(b: Int => Boolean): Boolean
foo1(9) { i => false }
def foo2(a: Int, b: Int => Boolean): Boolean
foo2(9, { i => false })
Related
I'm getting problems to understand the currying concept, or at least the SCALA currying notation.
wikipedia says that currying is the technique of translating the evaluation of a function that takes multiple arguments into evaluating a sequence of functions, each with a single argument.
Following this explanation, are the two next lines the same for scala?
def addCurr(a: String)(b: String): String = {a + " " + b}
def add(a:String): String => String = {b => a + " " + b}
I've run both lines with the same strings a and b getting the same result, but I don't know if they are different under the hood
My way of thinking about addCurr (and currying itself) is that it is a function that receives a string parameter a, and returns another function that also receives a string parameter b and returns the string a + " " + b?
So if I'm getting right, addCurr is only syntactic sugar of the function add and both are curryed functions?
According to the previous example, the next functions are also equivalent for scala?
def add(a: String)(b: String)(c: String):String = { a + " " + b + " " + c}
def add1(a: String)(b: String): String => String = {c => a + " " + b + " " + c}
def add2(a:String): (String => (String => String)) = {b => (c => a + " " + b + " " + c)}
They have a bit different semantics, but their use-cases are mostly the same, both practically and how it looks in the code.
Currying
Currying a function in Scala in that mathematical sense is a very straightforward:
val function = (x: Int, y: Int, z: Int) => 0
// function: (Int, Int, Int) => Int = <function3>
function.curried
// res0: Int => (Int => (Int => Int)) = <function1>
Functions & methods
You seem to be confused by the fact that in Scala, (=>) functions are not the same as (def) methods. Method isn't a first-class object, while function is (i.e. it has curried and tupled methods, and Function1 has even more goodness).
Methods, however, can be lifted to functions by an operation known as eta expansion. See this SO answer for some details. You can trigger it manually by writing methodName _, or it will be done implicitly if you give a method to where a function type is expected.
def sumAndAdd4(i: Int, j: Int) = i + j + 4
// sumAndAdd4.curried // <- won't compile
val asFunction = sumAndAdd4 _ // trigger eta expansion
// asFunction: (Int, Int) => Int = <function2>
val asFunction2: (Int, Int) => Int = sumAndAdd4
// asFunction2: (Int, Int) => Int = <function2>
val asFunction3 = sumAndAdd4: (Int, Int) => Int
// asFunction3: (Int, Int) => Int = <function2>
asFunction.curried
// res0: Int => (Int => Int) = <function1>
asFunction2.curried
// res1: Int => (Int => Int) = <function1>
asFunction3.curried
// res2: Int => (Int => Int) = <function1>
{sumAndAdd4 _}.tupled // you can do it inline too
// res3: Int => (Int => Int) = <function1>
Eta expansion of multiple parameter list
Like you might expect, eta expansion lifts every parameter list to its own function
def singleArgumentList(x: Int, y: Int) = x + y
def twoArgumentLists(x: Int)(y: Int) = x + y
singleArgumentList _ // (Int, Int) => Int
twoArgumentLists _ // Int => (Int => Int) - curried!
val testSubject = List(1, 2, 3)
testSubject.reduce(singleArgumentList) // Int (6)
testSubject.map(twoArgumentLists) // List[Int => Int]
// testSubject.map(singleArgumentList) // does not compile, map needs Int => A
// testSubject.reduce(twoArgumentLists) // does not compile, reduce needs (Int, Int) => Int
But it's not that currying in mathematical sense:
def hmm(i: Int, j: Int)(s: String, t: String) = s"$i, $j; $s - $t"
{hmm _} // (Int, Int) => (String, String) => String
Here, we get a function of two arguments, returning another function of two arguments.
And it's not that straightforward to specify only some of its argume
val function = hmm(5, 6) _ // <- still need that underscore!
Where as with functions, you get back a function without any fuss:
val alreadyFunction = (i: Int, j: Int) => (k: Int) => i + j + k
val f = alreadyFunction(4, 5) // Int => Int
Do which way you like it - Scala is fairly un-opinionated about many things. I prefer multiple parameter lists, personally, because more often than not I'll need to partially apply a function and then pass it somewhere, where the remaining parameters will be given, so I don't need to explicitly do eta-expansion, and I get to enjoy a terser syntax at method definition site.
Curried methods are syntactic sugar, you were right about this part. But this syntactic sugar is a bit different. Consider following example:
def addCur(a: String)(b: String): String = { a + b }
def add(a: String): String => String = { b => a + b }
val functionFirst: String => String = add("34")
val functionFirst2 = add("34")_
val functionSecond: String => String = add("34")
Generaly speaking curried methods allows for partial application and are necessary for the scala implicits mechanism to work. In the example above i provided examples of usage, as you can see in the second one we have to use underscore sign to allow compiler to do the "trick". If it was not present you would receive error similar to the following one:
Error:(75, 19) missing argument list for method curried in object XXX
Unapplied methods are only converted to functions when a function type
is expected. You can make this conversion explicit by writing curried_ or curried(_)(_) instead of curried.
Your question interested me so I tried this out my self. They actually desugar down to some very different constructs. Using
def addCurr(a: String)(b: String): String = {a + " " + b}
This actually compiles to
def addCurr(a: String, b: String): String = {a + " " + b}
So it completely removes any currying effect, making it a regular arity-2 method. Eta expansion is used to allow you to curry it.
def add(a:String): String => String = {b => a + " " + b}
This one works as you would expect, compiling to a method that returns a Function1[String,String]
Hi I am new to Scala and trying to call a higher order function sum_of from main class.I am getting "Cannot resolve reference sumOf with such signature error".
object SumOf {
def main(args: Array[String]) {
val y = sumOf(x=>x ,4,5)
println(y)
}
def sumOf(f: Int => Int)(a: Int, b: Int): Int = {
def loop(a: Int, acc: Int): Int =
if (a > b) acc
else loop(a + 1, f(a) + acc)
loop(a, 0)
}
}
sumOf is a curried function so it takes two arguments in the form of sumOf(x => x)(4,5) which is different from sumOf(x => x, 4,5). This is the reason you are getting an error.
Further, you can call it with only one argument sumOf(x => x) _ which returns another function that takes the second argument
(Int, Int) => Int = <function2> and return a function. This is more commonly known as partial function application.
Your sumOf method has two argument lists, and needs to be called with two argument lists.
val y = sumOf(x => x)(4, 5)
You can think of sumOf as a function which takes an Int => Int and returns a new function, which takes two Ints to return an Int.
According to ScalaByExample:
A curried function definition def f (args1) ... (argsn) = E where n >
1 expands to
def f (args1) ... (argsn−1) = { def g (argsn) = E ; g }
Or, shorter, using an anonymous function:
def f (args1) ... (argsn−1) = ( argsn ) => E
Uncurried version:
def f(x: Int): Int => Int = {
y: Int => x * y
} //> f: (x: Int)Int => Int
def f1 = f(10) //> f1: => Int => Int
f1(5)
Curried version:
def g(x: Int)(y: Int) = {
x * y
} //> g: (x: Int)(y: Int)Int
def g1 = g(10) _ //> g1: => Int => Int
g1(5)
The question is, Why curried required the underscore in line #5 in the second code snippet.
You can find the explanation at Martin Odersky book: http://www.artima.com/pins1ed/functions-and-closures.html (search for "Why the trailing underscore").
In short this is because Scala is closer to Java in a lot of things, rather than functional languages where this is not required. This helps you to find out mistakes at compile time, if you forgot the missing argument.
If underscore was not required, the next code will compile:
println(g(10))
And this check helps you preventing such mistakes
There are some cases though, when such calls are obvious, and underscore is not required:
def g(x: Int)(y: Int) = {
x * y
}
def d(f: Int => Int) {
f(5)
}
d(g(10)) // No need to write d(g(2) _)
// Or any other way you can specify the correct type
val p: Int => Int = g(10)
Something to note: in Scala, def's are methods, not functions, at least, not directly. Methods are converted to functions by the compiler every time a method is used where a function would be required, but strictly speaking, a function would be created with val instead, like so:
val curry = (x: Int) => (y: Int) => x * y
This allows you to apply arguments one at a time without having to add a trailing underscore. It functions identically to the code in your first snippet, but because it uses val and not def, curry cannot be written like
val curry(x: Int) = (y: Int) => x * y //Won't compile
So, when you want to write a function that behaves the way you want a curried function to behave, write it like I did in my first snippet. You can keep chaining parameters with => as many times as you want (up to technical limits, but good luck hitting them).
scala> def a(i:Int)(j:Int) = i * j
a: (i: Int)(j: Int)Int
scala> def b(i:Int, j:Int) = i * j
b: (i: Int, j: Int)Int
The two definitions are very similar, and they (appear to me) do the same thing.
Apart from defining a function which receives implicit parameters or a code block as parameter, is there any reason to use the first definition style?
This is the list I have compiled over the time:
1) Type resolution across multiple argument lists
class ResourceManager {
type Resource
def open: Resource = ???
}
class ResourceManagerTest {
// Does not compile: def test1(rm: ResourceManager, r: rm.Resource) = ???
// Compiles: This way the type can be resolved
def test2(rm: ResourceManager)(r: rm.Resource) = ???
}
2) Type inference where earlier arguments can "lock down" type parameters for later arguments (thanks to Myserious Dan)
def foo1[A](x: A, f: A => Int) = ???
def foo2[A](x: A)(f: A => Int) = ???
def foo1foo2Demo() {
// This will always demand a type annotation on any anonymous function
// you pass in:
foo1(1, (i: Int) => i * i)
// Does not compile: foo1(1, i => i * i)
// Type not required
foo2(2)(i => i * i)
}
3) Syntax-like language extensions
object MultipleArgumentListsDemo {
// This style of function definition allows syntax-like language extensions
#tailrec
def myWhile(conditional: => Boolean)(f: => Unit) {
if (conditional) {
f
myWhile(conditional)(f)
}
}
def myWhileDemo() {
var count = 0
myWhile(count < 5) {
count += 1
println(count)
}
}
4) Having both implicit and non implicit arguments, as implicit is a modifier for a whole argument list:
def f[A](x: A)(implicit mf: Manifest[A]) {
}
5) A parameter's value from one parameter list can be used to compute a default value in another parameter list, but not in the same one.
def g(x: Int)(y: Int = x * 2) = {
x + y
}
6) Multiple repeated argument lists ("varargs")
def h(as: Int*)(bs: Int*)(cs: Int*) = as.sum * bs.sum * cs.sum
7) Partial application
def i() {
val foop = h(1, 2, 3)(4, 5, 6, 7, 9) _
println(foop(Seq(10, 11)))
}
As I have not tracked my sources while I was compiling that list over the time: It's possible that some or all examples are copied from elsewhere (other questions on SO), so please drop a note, and I will add the reference as to where it came from.
The main reason for "currying" functions in this manner is to enable partial application:
scala> val c = a(5) _
c: Int => Int = <function1>
Here c is a function that takes a single int and returns the result of multiplying that int with 5. It may be that you would set up c in one method, and pass it into another method that expects a function taking one Int parameter. A bit trivial in this case, but very flexible for a range of uses.
Additional to support currying, it also helps with type inference: Sometimes the compiler can't infer the correct type if everything is in one argument list, but if you split off the part that depends on the binding of the other arguments, it works. A typical example is foldLeft: Try to implement it with one argument list, and then in some cases the compiler needs type annotations.
I'm trying to understand the advantages of currying over partial applications in Scala. Please consider the following code:
def sum(f: Int => Int) = (a: Int, b: Int) => f(a) + f(b)
def sum2(f: Int => Int, a: Int, b: Int): Int = f(a) + f(b)
def sum3(f: Int => Int)(a: Int, b: Int): Int = f(a) + f(b)
val ho = sum({identity})
val partial = sum2({ identity }, _, _)
val currying = sum3({ identity })
val a = currying(2, 2)
val b = partial(2, 2)
val c = ho(2, 2)
So, if I can calculate partially applied function that easy, what are the advantages of currying?
Currying is mostly used if the second parameter section is a function or a by name parameter. This has two advantages. First, the function argument can then look like a code block enclosed in braces. E.g.
using(new File(name)) { f =>
...
}
This reads better than the uncurried alternative:
using(new File(name), f => {
...
})
Second, and more importantly, type inference can usually figure out the function's parameter type, so it does not have to be given at the call site.
For instance, if I define a max function over lists like this:
def max[T](xs: List[T])(compare: (T, T) => Boolean)
I can call it like this:
max(List(1, -3, 43, 0)) ((x, y) => x < y)
or even shorter:
max(List(1, -3, 43, 0)) (_ < _)
If I defined max as an uncurried function, this would not work, I'd have to call it like this:
max(List(1, -3, 43, 0), (x: Int, y: Int) => x < y)
If the last parameter is not a function or by-name parameter, I would not advise currying. Scala's _ notatation is amost as lightweight, more flexible, and IMO clearer.
I think it becomes clearer if you invert your curried example:
def sum4(a: Int, b: Int)(f: Int => Int): Int = f(a) + f(b)
val d = sum4(2, 2) { x =>
x * x
}
It is more of an optical effect but you don’t need to use any parentheses around the whole expression. Of course you can achieve the same result using partial application or by creating a helper method to invert the arguments, sure. The point is, that you don’t have to do all of this if you start with a curried method in the first place. In that sense currying is more of an API and syntax sugar thing. It is not expected that you use
val partial_sum4 = sum4(2, 2)
anywhere in your code or that this is in any way especially meaningful to do. It is just that you get a nicely looking expression easily.
(Well, and there are some advantages with respect to type inference…)