Decoding class with type type

Given:

Given the following on ammonite:

@ import $ivy.`io.circe::circe-core:0.9.0` @ import $ivy.`io.circe::circe-generic:0.9.0` @ import $ivy.`com.chuusai::shapeless:2.3.3` @ import shapeless.tag import shapeless.tag @ trait Foo defined trait Foo @ import io.circe._, io.circe.generic.semiauto._ import io.circe._, io.circe.generic.semiauto._ @ import shapeless.tag.@@ import shapeless.tag.@@ @ implicit def taggedTypeDecoder[A, B](implicit ev: Decoder[A]): Decoder[A @@ B] = ev.map(tag[B][A](_)) defined function taggedTypeDecoder 

Given Foo :

 @ case class F(x: String @@ Foo) defined class F 

I can call Decoder[String @@ Foo] :

 @ Decoder[String @@ Foo] res17: Decoder[String @@ Foo] = io.circe.Decoder$$anon$21@16b32e49 

But not F :

 @ deriveDecoder[F] cmd18.sc:1: could not find Lazy implicit value of type io.circe.generic.decoding.DerivedDecoder[ammonite.$sess.cmd16.F] val res18 = deriveDecoder[F] ^ Compilation Failed 

How can I get Decoder[F] ?

+3
scala shapeless circe
source share
1 answer

This is a mistake in the formless < Lazy - milessabin / unteless # 309

I have a PR that forces your example to compile - milessabin / shapeless # 797 (I checked with publishLocal )

The main problem with Lazy is that it extends type aliases too much ( A @@ B is a type alias for A with Tagged[B] ), which in turn causes a Scala error - scala / error # 10506

Scala error does not have a clear solution. This is another embodiment of the problem of subtyping and parametric polymorphism, which complicates the conclusion of the type. Its essence is that Scala must perform a subtype check and output at the same time. But when we put some type variables, such as A and B into a sophisticated type, like A with Tagged[B] (in fact, circe finishes searching for FieldType[K, A with Tagged[B]] , where FieldType is another type alias that hides specified type), subtyping should be checked for each component separately. This means that the order in which we select component testing determines how variables of type A and B will be constrained. In some cases, they are too or too limited and cannot be displayed correctly.

Apropo, formless tests show a workaround , but I don’t think it applies to circe, because it uses some kind of macro, and how to do a vanilla type derivation.

In short, you can:

  • Wait for the formless (please upvote # 797 ) and the subsequent release of circe
  • Do not use tagged tags = /
  • Try using a different encoding without refined or structured types - maybe alexknvl / newtypes ? (I have not tried)
+5
source share

All Articles