[英]Blending Magnolia with Circe's trick for automatic derivation
I've got a typeclass and want to provide semi-automatic and automatic derivation to users. 我有一个类型类,并希望为用户提供半自动和自动派生。 I have a working implementation based on Magnolia and it works really well. 我有一个基于Magnolia 的工作实现 ,它工作得非常好。 There's a trait providing definitions for Typeclass[A]
, combine[A]
and dispatch[A]
, then both types of derivation are accessible with 有一个特征为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]
}
Nothing surprising. 没什么好惊讶的。 Not surprising either is that when users bring auto._
into scope, it overshadows efficient derivations written for specific types. 也就是说,当用户将auto._
带入范围时,它会掩盖为特定类型编写的高效派生,这也就auto._
了。
I was hoping I could use the same technique Travis Brown devised for Circe, which basically works like this: 我希望我可以使用Travis Brown为Circe设计的相同技术,它基本上是这样的:
Define a placeholder value class that can hold on any value 定义可以保留任何值的占位符值类
case class Exported[A](instance: A) extends AnyVal
Provide a low-priority automatic derivation for my typeclass when a value of that class is in scope 当该类的值在范围内时,为我的类型类提供低优先级自动派生
object DynamoFormat extends LowPriorityDerivation {
// derivation for specific types
...
}
trait LowPriorityDerivation {
implicit def deriveExported[A](implicit e: Exported[DynamoFormat[A]]) =
e.instance
}
Finally, hide automatic derivation of exported objects in auto
最后,隐藏auto
中导出对象的自动派生
final object auto extends Derivation {
implicit def derive[A]: Exported[DynamoFormat[A]] =
Exported(semiauto.deriveFormat[A])
}
Sadly there's a compilation error when trying to summon the macro: 遗憾的是,在尝试召唤宏时出现编译错误:
magnolia: could not infer auto.Typeclass for type com.gu.scanamo.DynamoFormat[A]
Exported(deriveDynamoFormat[A])
^
I've been looking at this code for too long now that I can't find a way out; 我一直在看这段代码已经太久了,因为我找不到出路; any help would be greatly appreciated. 任何帮助将不胜感激。
maybe you can use a macro wrap it 也许你可以使用宏包装它
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.