Heinzi Heinzi - 3 months ago 22
Scala Question

Scala: Multiple implicit conversions with same name

Using scala 2.10.3, my goal is to make the following work:

object A {
implicit class Imp(i: Int) {
def myPrint() {
println(i)
}
}
}

object B {
implicit class Imp(i: String) {
def myPrint() {
println(i)
}
}
}

import A._
import B._

object MyApp extends App {
3.myPrint()
}


This fails with

value myPrint is not a member of Int


If I give A.Imp and B.Imp different names (for example A.Imp1 and B.Imp2), it works.

Diving a bit deeper into it, there seems to be the same problem with implicit conversions.

This works:

object A {
implicit def Imp(i: Int) = new {
def myPrint() {
println(i)
}
}

implicit def Imp(i: String) = new {
def myPrint() {
println(i)
}
}
}

import A._

object MyApp extends App {
3.myPrint()
}


Whereas this doesn't:

object A {
implicit def Imp(i: Int) = new {
def myPrint() {
println(i)
}
}
}

object B {
implicit def Imp(i: String) = new {
def myPrint() {
println(i)
}
}
}

import A._
import B._

object MyApp extends App {
3.myPrint()
}


Why? Is this a bug in the scala compiler? I need this scenario, since my objects A and B derive from the same trait (with a type parameter) which then defines the implicit conversion for its type parameter. In this trait, I can only give one name for the implicit conversion. I want to be able to import more of these objects into my scope. Is there a way to do that?

edit: I can't give the implicit classes different names, since the examples above are only breaking down the problem. My actual code looks more like

trait P[T] {
implicit class Imp(i: T) {
def myPrint() {
...
}
}
}

object A extends P[Int]
object B extends P[String]

import A._
import B._

Answer

The implicits just have to be available as a simple name, so you can rename on import.

Just to verify:

scala> import A._ ; import B.{ Imp => BImp, _ }
import A._
import B.{Imp=>BImp, _}

scala> 3.myPrint
3