Reputation: 1457
So I am a bit confused as to how curried functions in Scala work. I have the following code which compiles, but I am not sure how!
def fixedPoint(f: Double => Double, initialGuess: Double) = {
//dummy impl, does nothing.
}
def averageDamp(f: Double => Double)(x: Double) = (x + f(x))/2
def sqrt(x: Int) = {
fixedPoint(averageDamp(y => x/y))(1)
}
This code compiles fine, but I would have thought averageDamp
needs to also take another parameter? So it should be :
fixedPoint(averageDamp(y=> x/y)(1))(1)
But this does not compile, and i get a message saying type mismatch; found : Double required: Double ⇒ Double
The following does not compile, which makes sense:
val num = averageDamp(y => x/y)
This gives the compile error message : "missing argument list for method averageDamp in object Foo Unapplied methods are only converted to functions when a function type is expected."
So I am not sure why it compiles when calling averageDamp with one parameter inside the call to fixedPoint, but fails to compile when i call it on its own.
Any help would be great.
Upvotes: 3
Views: 4329
Reputation: 8663
This is the code that compiles
def fixedPoint(f: Double => Double, initialGuess: Double) = {
//dummy impl, does nothing.
}
def averageDamp(f: Double => Double)(x: Double) = (x + f(x))/2
def sqrt(x: Int) = {
fixedPoint(averageDamp(y => x/y), 1)
}
At this line
fixedPoint(averageDamp(y => x/y), 1)
even though averageDamp
needs one more parameter list (that has one more parameter) it is valid not to put it. Actually this is the reason why it was defined as curried in the first place - so that you can use it as a function.
scala> val num = averageDamp(y => 5/y)(1)
num: Double = 3.0
would give you a result of type Double
as you probably expect.
If you don't pass the second parameter list you can receive a function
val fun = averageDamp(y => 5/y)
gives you an error tries to tell you that you need to inform compiler that you want fun
to be a function. You can do this in following ways:
scala> val fun: Double => Double = averageDamp(y => 5/y)
fun: Double => Double = <function1>
scala> val fun = averageDamp(y => 5/y) _
fun: Double => Double = <function1>
Now look at fixedPoint
def fixedPoint(f: Double => Double, initialGuess: Double)
it expects a function Double => Double
so we can pass it
fixedPoint(averageDamp(y => 5/y), 1)
compiler knows that first parameter should be a function and with this knowledge it converts this method to a function that has yet to take that x: Double
parameter and will return (x + f(x))/2
Upvotes: 7