Suma
Suma

Reputation: 34403

Make an implicit from a different object accessible when my object is imported

When someone imports my object, I would like some implicit classes from other objects (or packages) to be available to them. Having import in the object does not help, as imports are not imported transitively, therefore I assume I must use some implicit def or val, however I am unable to find some reasonable way how to achieve this, only a quite verbose def:

object Main extends App {

  object A {

    implicit class ExtendedMath(val x: Double) extends AnyVal {
      def square = x * x
    }

  }

  object X {

    import A._

    // what to write here, so that ExtendedMath is forwarded to our users?
    // following works, but it seems quite verbose
    implicit def extendedMath(x: Double): ExtendedMath = ExtendedMath(x)
  }


  import X._
  val a = 0.0
  println(a.square)
}

Is there some more concise way?

Upvotes: 1

Views: 721

Answers (1)

0__
0__

Reputation: 67280

As @stew suggests, the typical approach is to define the implicits in a trait that you can then mix in multiple times. The only caveat is that value classes are not allowed inside a trait, so you have to resort to separating value class and implicit conversion:

class ExtendedMath(val x: Double) extends AnyVal {
  def square = x * x
}

trait HasMath {
  // note: method name somehow must not shadow
  // value class name, therefore we use lower-case
  implicit def extendedMath(x: Double): ExtendedMath = new ExtendedMath(x)
}

object A extends HasMath

object X extends HasMath

object Test {
  import X._
  4.0.square
}

Upvotes: 3

Related Questions