Смешивание магнолии с трюком Цирцеи для автоматического получения

У меня есть класс типов и я хочу предоставить пользователям полуавтоматический и автоматический вывод. У меня есть рабочая реализация, основанная на Magnolia, и она работает очень хорошо. Есть черта, дающая определения Typeclass[A], combine[A] а также dispatch[A], тогда оба типа деривации доступны с

final object semiauto extends Derivation {
  def deriveFormat[A]: Typeclass[A] = macro Magnolia.gen[A]
}

final object auto extends Derivation {
  implicit def deriveFormat[A]: Typeclass[A] = macro Magnolia.gen[A]
}

Ничего удивительного. Не удивительно, что когда пользователи приносят auto._ в область видимости затмевает эффективные деривации, написанные для определенных типов.

Я надеялся, что смогу использовать ту же технику, которую разработал Трэвис Браун для Circe, которая в основном работает так:

Определите класс значения заполнителя, который может содержать любое значение

case class Exported[A](instance: A) extends AnyVal

Предоставить низкоприоритетный автоматический вывод для моего класса типов, когда значение этого класса находится в области видимости

object DynamoFormat extends LowPriorityDerivation {
  // derivation for specific types
  ...
}

trait LowPriorityDerivation {
  implicit def deriveExported[A](implicit e: Exported[DynamoFormat[A]]) =
    e.instance
}

Наконец, скрыть автоматический вывод экспортируемых объектов вauto

final object auto extends Derivation {
  implicit def derive[A]: Exported[DynamoFormat[A]] =
    Exported(semiauto.deriveFormat[A])
}

К сожалению, есть ошибка компиляции при попытке вызвать макрос:

magnolia: could not infer auto.Typeclass for type com.gu.scanamo.DynamoFormat[A]
    Exported(deriveDynamoFormat[A])
                               ^

Я слишком долго смотрю на этот код, потому что не могу найти выход; любая помощь будет принята с благодарностью.

1 ответ

Может быть, вы можете использовать макрос обернуть его

object MacroWrap {

  def typeName[T]: String = macro typeNameImpl[T]

  def typeNameImpl[T: c.WeakTypeTag](c: blackbox.Context): c.universe.Tree = {
    import c.universe._
    q"${c.weakTypeOf[T].toString}"
  }

  def typeNameWeak[T]: String = macro typeNameWeakImpl[T]

  def typeNameWeakImpl[T: c.WeakTypeTag](c: blackbox.Context) = {
    import c.universe._
    q"${reify(MacroWrap)}.typeName[${weakTypeOf[T]}]"
  }
}

//тестовое задание

println(MacroWrap.typeNameWeak[String]) // will print String
Другие вопросы по тегам