3

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.

1
  • your code that you claim compiles actually does not because of missing parameter... Commented Jun 18, 2016 at 22:36

1 Answer 1

7

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

Sign up to request clarification or add additional context in comments.

2 Comments

"even though averageDamp needs one more parameter list which happens to have one parameter ..." You can only leave out the whole parameter list(s).
I know, it is mentioned later that ommiting applies to lists of parameters, I didn't want to complicate it from the beginning. I think the sentence itself is true in the given context unless you go deep into semantics, but I will edit it for clarity. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.