Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
argonaut union type example
package argonaut.example
import argonaut._, Argonaut._
import scalaz._, Scalaz._
object UnionExample extends {
sealed trait Thing
final case class One(n: String, i: Int) extends Thing
final case class Two(n: String) extends Thing
case object Three extends Thing
implicit def ThingEncodeJson: EncodeJson[Thing] =
EncodeJson(_ match {
case One(n, i) => Json("one" := Json("name" := n, "age" := i))
case Two(n) => Json("two" := Json("name" := n))
case Three => Json("three" := ())
})
implicit def ThingDecodeJson: DecodeJson[Thing] =
DecodeJson(c =>
tagged("one", c, jdecode2L(One.apply)("name", "age")) |||
tagged("two", c, jdecode1L(Two.apply)("name")) |||
tagged("three", c, implicitly[DecodeJson[Unit]].map(_ => Three)))
def tagged[A](tag: String, c: HCursor, decoder: DecodeJson[A]): DecodeResult[A] =
(c --\ tag).hcursor.fold(DecodeResult.fail[A]("Invalid tagged type", c.history))(decoder.decode)
}
@toby5box

This comment has been minimized.

Copy link

toby5box commented Apr 4, 2015

Mark, is there an update to this example? I get:

UnionExample.scala:21: type mismatch;
[error] found : argonaut.DecodeResult[UnionExample.Two]
[error] required: argonaut.DecodeResult[Product with Serializable with UnionExample.Thing]
[error] Note: UnionExample.Two <: Product with Serializable with UnionExample.Thing, but class DecodeResult is invariant in type A.
[error] You may wish to define A as +A instead. (SLS 4.5)
[error] tagged("two", c, jdecode1L(Two.apply)("name")) |||
[error] ^

@toby5box

This comment has been minimized.

Copy link

toby5box commented Apr 4, 2015

Never mind, it's possible to just widen the type to the common supertype, using another map[T], scalaz widen, or in my case, simple ascription of the supertype to a case object or case class constructor.

(h/t @tpolecat for leading me to the finish line on this one)

@mkalish

This comment has been minimized.

Copy link

mkalish commented Oct 4, 2016

Hi @toby5box... do you happen to have an updated example on how you got the gist working?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.