4

Compiling this code:

class Test {

  def f(arg: Int)(defaultArg: String => Unit = println): Unit = ???

  f(42)
}

fails with

missing argument list for method f in class Test [error] Unapplied methods are only converted to functions when a function type is expected. [error] You can make this conversion explicit by writing `f _` or `f(_)(_)` instead of `f`. [error] f(42) [error] ^ [error] one error found

Why does it fail? Does it introduce ambiguity? Is it possible to make it work w/o resorting to single parameters list?

2 Answers 2

10

The correct syntax for your case is the following:

f(42)()

You can make call to f(42) work by defining defaultArg as implicit:

def f(arg: Int)(implicit defaultArg: String => Unit = println): Unit = ???

Then you can call it:

f(42)
Sign up to request clarification or add additional context in comments.

1 Comment

Ah, so you have to specify () for parameters list unless it is implicit parameters list
0

So you are passing a Int argument to a method and a function that can print it. Now when you say f(42) the compiler would see that the function can be applied to the Int and result in another function. That is it see this is a case of partially applied function. So when you make the call f(42) the result is another function.So the compiler complains saying that you should either pass in the second argument or treat this result as a partially applied function.

Consider the following code,

val ptln1:String=>Unit = System.out.println _ //Doing this to show the type of the println function
def f(arg: Int)(defaultArg: String => Unit = ptln1): Unit = ???
val t = f(42)()

As you can see i have written the types explicitly so it makes sense.
So now you could either pass the function using implicits as below,

def f(arg: Int)(implicit defaultArg: String => Unit = println _): Unit = ???
f(42)()

Or this without implicits ,

  def f(arg: Int)(defaultArg: String => Unit = println _): Unit = ???
  val t = f(42)()

Also consider the following optionally if i use a self defined function instead of the println . Maybe this will make it clearer.

implicit def testPrint(str:String):Unit = ???

   def f(arg: Int)(implicit defaultArg: String => Unit = testPrint): Unit = ???

   val t = f(42)

Or without implicits ,

   def testPrint(str:String):Unit = ???

   def f(arg: Int)(defaultArg: String => Unit = testPrint): Unit = ???

   val t = f(42)()

Comments

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.