argonaut-shapeless
argonaut-shapeless copied to clipboard
problem encoding tagged types
I have an example where I can't derive an instance for a case class even though I do have instances for all the members of the case class:
scalaVersion := "2.11.7"
resolvers += Resolver.sonatypeRepo("releases")
libraryDependencies +=
"com.github.alexarchambault" %% "argonaut-shapeless_6.1" % "0.3.1"
import scalaz.{@@, Tag}
import argonaut._, Argonaut._, Shapeless._
trait MyTag
case class Foo(s: String)
case class Bar(s: String @@ MyTag)
object Main extends App {
implicit def encodeTagged[A,T](implicit A: EncodeJson[A]): EncodeJson[A @@ T] =
A.contramap(Tag.of[T].unwrap)
implicitly[EncodeJson[Foo]] // ok
implicitly[EncodeJson[String @@ MyTag]] // ok
implicitly[EncodeJson[Bar]] // could not find argonaut.EncodeJson[Bar]
println("hooray!")
}
above code is reproduced at http://scastie.org/12249
The derivation provided by argonaut does seem work though, whereas I can't seem to get argonaut-shapeless's to:
implicit val encodeBar: EncodeJson[Bar] = EncodeJson.derive[Bar]
implicitly[EncodeJson[Bar]] // ok!
http://scastie.org/12281
This is related to https://github.com/milessabin/shapeless/issues/309. Scalaz tagged types and shapeless records don't deal well together. https://github.com/milessabin/shapeless/issues/309 gives a workaround, which would involve writing alternatives to hconsEncodeJson and hconsDecodeJson methods specifically taillored for scalaz tagged types. It should be possible fto write these manually, and put them in scope when deriving these codecs.
I wonder if it’s any different with shapeless tags instead of scalaz tags. I’m not really tied to the latter. Won’t have a chance to give it a try until next week though.