繁体   English   中英

将Magnolia与Circe的技巧融合在一起,实现自动推导

[英]Blending Magnolia with Circe's trick for automatic derivation

我有一个类型类,并希望为用户提供半自动和自动派生。 我有一个基于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._带入范围时,它会掩盖为特定类型编写的高效派生,这也就auto._了。

我希望我可以使用Travis Brown为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])
                               ^

我一直在看这段代码已经太久了,因为我找不到出路; 任何帮助将不胜感激。

也许你可以使用宏包装它

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM