Artem Sokolov
Artem Sokolov

Reputation: 43

Unapplied method to function conversion not working for parameters in overloaded functions

Below I have two pieces of code. First one compiles just fine:

object StackOverflow {
  class TwoMethods {
    def setString(string: String): Unit = {}
    def setLong(long: Long): Unit = {}
  }

  def populate[T](f: T => Unit, value: Option[Any]): Unit = {
    value.foreach(x => f(x.asInstanceOf[T]))
  }

  def someMethod(twoMethods: TwoMethods): Unit = {
    populate(twoMethods.setString, Some("string"): Option[Any])
    populate(twoMethods.setLong, None: Option[Long])
  }
}

However, if populate method is overloaded, then compiler asks me to add underscore to the unapplied method for conversion to function to work (following doesn't compile):

object StackOverflow {
  class TwoMethods {
    def setString(string: String): Unit = {}
    def setLong(long: Long): Unit = {}
  }

  def populate[T](f: T => Unit, value: Option[T]): Unit = {
    value.foreach(f(_))
  }

  def populate[X: ClassTag](f: String => Unit, value: Option[Any]): Unit = {
    value.foreach(x => f(x.toString))
  }

  def someMethod(twoMethods: TwoMethods): Unit = {
    populate(twoMethods.setString, Some("string"): Option[Any])
    populate(twoMethods.setLong, None: Option[Long])
  }
}

It wants me to change it to this in order to work:

...
populate(twoMethods.setString _, Some("string"): Option[Any])
populate(twoMethods.setLong _, None: Option[Long])
...

Why is this happening and how can I avoid adding underscores to the first parameter in each populate call?

Upvotes: 4

Views: 3200

Answers (1)

Joe Pallas
Joe Pallas

Reputation: 2155

The compiler must have type information about the arguments in order to resolve an overloaded method. So, it does not have "expected type" information available when it is looking at the arguments to an overloaded method. That is why it complains Unapplied methods are only converted to functions when a function type is expected.

Now, you and I know that every overloaded method is expecting a function, but the compiler doesn't try to interleave the two steps (maybe there's a potential combinatorial explosion in the search space?).

I think your only option to avoid this is to take overloading out of the picture.

Upvotes: 4

Related Questions