Why it is not possible to overload the argument method for an implicit class

I am trying to overload a method in an object Using the world of an implicit World class

class World {
}

object World {

  implicit class WithWorld(_world: World) {
    def world(): Unit = println("world")
  }

  implicit class WithWorld2(_world: World) {
    def world(i: List[Int]): Unit = println("list Int")
  }

  implicit class WithWorld3(_world: World) {
    def world(i: List[String]): Unit = println("list String")
  }


}

// test

val world = new World()

//it is right

world.world(List(1))
world.world(List("string"))

// but this world.world(), I get a compilation error

Error:(36, 5) type mismatch;
 found   : world.type (with underlying type World)
 required: ?{def world: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method WithWorld in object World of type (_world: World)World.WithWorld
 and method WithWorld2 in object World of type (_world: World)World.WithWorld2
 are possible conversion functions from world.type to ?{def world: ?}
    world.world()
    ^
+4
source share
1 answer

Sounds like a mistake, but it's hard to say. Usually you define all of these methods in one implicit class. But then you encounter an error when both receiving methods Listhave the same erase, and the compiler will not allow this. However, you can get around this using DummyImplicit:

class World

object World {

  implicit class WithWorld(_world: World) {
    def world(): Unit = println("world")
    def world(i: List[Int]): Unit = println("list Int")
    def world(i: List[String])(implicit d: DummyImplicit): Unit = println("list String")
  }

}

scala> val world = new World
world: World = World@4afcd809

scala> world.world()
world

scala> world.world(List(1, 2, 3))
list Int

scala> world.world(List("a", "b", "c"))
list String

Overloading a method usually leads to pain and suffering at some point.

+1
source

Source: https://habr.com/ru/post/1625717/


All Articles