Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Scala implicit resolution fail for overloaded method with type parameter?

The first example successfully finds the implicit conversion to the method foo(String), however as soon as I add a type parameter (see fails) the compiles doesn't resolve it anymore:

object works {
  class A {
    def foo(): String = ???
  }
  implicit class PimpedA(a: A) {
    def foo(i: String): String = ???
  }
  val a = new A()
  a.foo("test") //compiles
}

object fails { //same as `works`, but adds type parameter
  class A {
    def foo[T](): String = ???
  }
  implicit class PimpedA(a: A) {
    def foo[T](i: String): String = ???
  }
  val a = new A()
  PimpedA(a).foo("test") // compiles
  a.foo("test") // error: too many arguments for method foo: ()String
}

This behaviour is the same for Scala 2.11.7 and 2.12.0-M3.

The documentation on implicits doesn't seem to cover this and I didn't find this exact case on stackoverflow.

Note that my goal is to overload the method foo - if i rename it, the compiler finds it.

http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

like image 464
Michael Pollmeier Avatar asked Oct 16 '15 04:10

Michael Pollmeier


People also ask

What is implicit parameter in Scala?

Implicit parameters are the parameters that are passed to a function with implicit keyword in Scala, which means the values will be taken from the context in which they are called.

What is overloading in Scala?

What is Scala Method Overloading? Scala Method overloading is when one class has more than one method with the same name but different signature. This means that they may differ in the number of parameters, data types, or both. This makes for optimized code.


1 Answers

Both cases seem to fall under this case of the specification:

Views are applied in three situations:

...

In a selection e.m(args) with e of type T, if the selector m denotes some member(s) of T, but none of these members is applicable to the arguments args. In this case a view v is searched which is applicable to e and whose result contains a method m which is applicable to args. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of T. If such a view is found, the selection e.m is converted to v(e).m(args).

So it should work. I was actually surprised to see it, because I've never run into the working case before and assumed that there is no implicit search if T has any members named m. I've taken a quick look at http://issues.scala-lang.org/, but couldn't find a relevant issue.

like image 135
Alexey Romanov Avatar answered Sep 28 '22 14:09

Alexey Romanov