Смешивание магнолии с трюком Цирцеи для автоматического получения - PullRequest
0 голосов
/ 26 мая 2018

У меня есть класс типов и я хочу предоставить пользователям полуавтоматический и автоматический вывод.У меня есть рабочая реализация , основанная на 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 Ответ

0 голосов
/ 30 мая 2018

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

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]}]"
  }
}

// test

println(MacroWrap.typeNameWeak[String]) // will print String
...