alexarchambault / argonaut-shapeless

Automatic argonaut codec derivation with shapeless
BSD 3-Clause "New" or "Revised" License
99 stars 24 forks source link

problem encoding tagged types #31

Open aryairani opened 9 years ago

aryairani commented 9 years ago

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

aryairani commented 9 years ago

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

alexarchambault commented 9 years ago

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.

aryairani commented 9 years ago

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.