Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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._
like image 913
Heinzi Avatar asked Feb 28 '14 21:02

Heinzi


1 Answers

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
like image 132
som-snytt Avatar answered Nov 07 '22 09:11

som-snytt