【问题标题】:Decoding Case Class w/ Tagged Type带标记类型的解码案例类
【发布时间】:2018-06-18 21:04:43
【问题描述】:

给定:

鉴于以下关于菊石的情况:

@ 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

给定一个Foo

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

我可以召唤Decoder[String @@ Foo]

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

但不是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

如何获得Decoder[F]

【问题讨论】:

    标签: scala shapeless circe


    【解决方案1】:

    这是 shapeless 中的一个错误'Lazy - milessabin/shapeless#309

    我有一个 PR 可以编译你的示例 - milessabin/shapeless#797(我检查了 publishLocal

    Lazy 中的问题基本上是它过于急切地扩展类型别名(A @@ BA with Tagged[B] 的类型别名),这反过来又会触发 Scala 错误 - scala/bug#10506

    Scala 错误目前还没有明确的解决方案。这是使类型推断复杂化的子类型与参数多态性问题的另一个体现。它的要点是 Scala 必须同时执行子类型检查和类型推断。但是,当我们将一些类型变量(如 AB必须单独检查每个组件。这意味着我们选择检查组件的顺序决定了类型变量AB 将如何受到约束。在某些情况下,它们最终会受到过度或不足的约束,无法正确推断。

    顺便说一句,无形测试显示workaround,但我认为它不适用于circe,因为它使用某种宏而不是进行普通类型类派生。

    长话短说,您可以:

    1. 等待无形(请支持#797)和随后的循环发布
    2. 不使用标记类型 =/
    3. 尝试使用不经过精炼或结构化类型的不同编码 - 可能是alexknvl/newtypes? (我没试过)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-15
      • 2018-06-18
      • 2018-10-22
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 2019-03-09
      相关资源
      最近更新 更多