Kev*_*ith 6 scala shapeless circe
鉴于:
鉴于以下关于亚扪人:
@ 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
Run Code Online (Sandbox Code Playgroud)
鉴于Foo:
@ case class F(x: String @@ Foo)
defined class F
Run Code Online (Sandbox Code Playgroud)
我可以召唤一个Decoder[String @@ Foo]:
@ Decoder[String @@ Foo]
res17: Decoder[String @@ Foo] = io.circe.Decoder$$anon$21@16b32e49
Run Code Online (Sandbox Code Playgroud)
但不是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
Run Code Online (Sandbox Code Playgroud)
我怎么能得到一个Decoder[F]?
这是一个无形的错误' Lazy- milessabin/shapeless#309
我有一个公关,让你的例子编译 - milessabin/shapeless#797(我检查过publishLocal)
基本上问题Lazy在于它过于急切地扩展类型别名(A @@ B是一个类型别名A with Tagged[B]),这反过来会触发Scala bug - scala/bug#10506
Scala bug看不到明确的解决方案.它是子类型与参数多态性问题的另一个化身,使类型推断变得复杂.它的要点是Scala执行子类型检查和类型推断在同一时间.但是,当我们把一些类型的变量,比如A和B一个精致的类型一样A with Tagged[B](实际上瑟茜结束了寻找FieldType[K, A with Tagged[B]]地方FieldType是另一种类型的别名隐藏精致型),子类型,必须为每个组件单独检查.这意味着,我们在其中选择检查组件的顺序决定了的类型变量A和B将受到限制.在某些情况下,它们会过度约束或约束不足,无法正确推断.
Apropo,无形测试显示了一种解决方法,但我不认为它适用于circe,因为它使用的是某种宏,而不是使用vanilla类型派生.
长话短说,你可以: