Сделать неявное из другого объекта доступным, когда мой объект импортируется

Когда кто-то импортирует мой объект, я хотел бы, чтобы ему были доступны некоторые неявные классы из других объектов (или пакетов). Наличие import в объекте не помогает, поскольку импорт не импортируется транзитивно, поэтому я предполагаю, что должен использовать некоторые implicit def или val, однако я не могу найти какой-либо разумный способ, как это сделать, только довольно подробный 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)
}

Есть ли более лаконичный способ?


person Suma    schedule 06.01.2016    source источник
comment
У вас есть контроль над пакетом, из которого вы хотите получить имплициты?   -  person Michael Zajac    schedule 07.01.2016
comment
@m-z В данном конкретном случае да, но я могу себе представить, что иногда хотелось бы пересылать неявные данные из сторонних пакетов.   -  person Suma    schedule 07.01.2016
comment
поместите неявное в черту, расширенную обоими объектами   -  person stew    schedule 07.01.2016


Ответы (1)


Как предполагает @stew, типичный подход состоит в том, чтобы определить имплициты в признаке, который затем можно смешивать несколько раз. Единственное предостережение заключается в том, что классы значений не разрешены внутри трейта, поэтому вам придется прибегнуть к разделению класса значений и неявного преобразования:

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
}
person 0__    schedule 07.01.2016
comment
поэтому вам придется прибегнуть к разделению класса значений и неявного преобразования: - учитывая, что это бремя не ложится на пользователей объекта, я считаю это приемлемым. Если это типичный подход, то есть ли у него какое-то название? - person Suma; 07.01.2016
comment
@Suma Я не знаю какого-либо конкретного имени, данного этому подходу. Но я видел это много раз, так что это обычное дело. - person 0__; 07.01.2016