Question

I'm trying to use implicits to allow me to write statements of the form 2*x, where x is of class X and needs to be implicitly converted to another type Y.

As far as I can tell, this means I also need to convert my Int to a class with a *(:Y) method. Scala doesn't seem to like it because Int already has a * method. Is there anything I can do to make this work other than giving my NewInt class a *(:X) method as well?

Minimally disfunctional example:

  class A
  class B
  class C
  class D {
    def *(other: B): B = null
  }

  implicit def a2b(x: A): B = new B
  implicit def c2d(x: C): D = new D

  (new C)*(new A) // This is fine:
                  // C is converted to D, and A is converted to B
                  // and D has a method *(:B)

  // But...

  class NewInt(val value: Int){
    def *(other: B): B = null
  }

  implicit def int2newint(x: Int): NewInt = new NewInt(x)


  (new NewInt(2))*(new A) // Fine
  2*(new B)               // Fine

  // ... here's the problem:
  2*(new A)               // Error, though if I add
                          //   def *(other: A): B = null
                          // to NewInt it is fine
Was it helpful?

Solution

You can do it with a view bound:

class NewInt(val value: Int){
  def *[T <% B](other: T): B = new B
}

[T <% B] means that T must be implicitly convertible to B, and so both A and B work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top