簡體   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