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. There's a trait providing definitions for Typeclass[A]
, combine[A]
and dispatch[A]
, then both types of derivation are accessible with
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.
I was hoping I could use the same technique Travis Brown devised for Circe, which basically works like this:
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
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
//test