问题
I am just new to Scala and it seems a little bit confusing to me why Scala provides "curried functions" such as:
//curried function
def add(lhs: Int)(rhs: Int) = lhs + rhs
//so we can do partially binding like
val add1 = add(1)_
Its confusing because Scala already provides 'partial application' to normal functions, e.g.,
//normal function
def add(lhs: Int, rhs: Int) = lhs + rhs
//also supports partially application
val add1 = add(1, _: Int)
So my question is: is there any other point of using a curried function rather than a normal function in Scala besides partial application?
EDT1: Thanks for the replies. I think I have learned new stuff from all the answers below.
回答1:
Putting the theoretical motivations aside (see: Contrast with partial function application in Wikipedia on currying), there is a practical implication. The syntax is much simpler and more readable when the last argument is a block of code.
Compare the following methods:
def test1(name: String, callback: => Unit) {}
def test2(name: String)(callback: => Unit) {}
The second method invocation looks much nicer, compare:
test("abc", {
//some code
})
test2("abc") {
//some code
}
回答2:
- Nicer syntax: add(1) instead of add(1,_)
- Type inference from the left to the right parameter list. This is used in the fold methods of collections, for example.
- They are also needed for implicit parameter lists.
Of course you could argue that the last two could have been implemented differently.
回答3:
I am not familiar with the theory behind currying (as yet), but I know of at least one concrete situation where currying works better: calling a function with a pair of curly braces instead of brackets is only possible for single-parameter functions. So you can do it for a curried function having two parameter lists with a single parameter each, but not for a normal function which has been partially applied for one parameter.
This is especially useful when implementing a control structure or DSL where some parameters of a function are anonymous functions themselves. An example to this is from Programming in Scala, section 9.4:
val file = new File("date.txt")
withPrintWriter(file) {
writer => writer.println(new java.util.Date)
}
来源:https://stackoverflow.com/questions/12635695/whats-the-rationale-behind-curried-functions-in-scala