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?
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
}