繁体   English   中英

解码无形标记类型

[英]Decoding Shapeless Tagged Types

鉴于以下关于亚扪人:

@ 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

它在明确拼写String @@ Foo

@ val x: String @@ Foo = tag[Foo][String]("foo") 
x: String @@ Foo = "foo"

@ implicitly[Decoder[String @@ Foo]] 
res10: Decoder[String @@ Foo] = io.circe.Decoder$$anon$21@2b17bb37

但是,在定义类型别名时:

@ type FooTypeAlias = String @@ Foo 
defined type FooTypeAlias

它没有编译:

@ implicitly[Decoder[FooTypeAlias]] 
cmd12.sc:1: diverging implicit expansion for type io.circe.Decoder[ammonite.$sess.cmd11.FooTypeAlias]
starting with method decodeTraversable in object Decoder
val res12 = implicitly[Decoder[FooTypeAlias]]
                      ^
Compilation Failed

这是为什么? 有没有已知的“修复?”

幸运的是,在同一天遇到两个编译器错误。 这个是scala / bug#8740 好吗? 新闻是在这个评论中有一个部分修复等待某人加强并制作PR(也许这就是你)。 我认为这是部分的,因为看起来它适用于特定的标签,但不适用于通用标签(我不是100%肯定)。

你看到一个不同的隐式扩张的原因真的很有趣。 编译器可以在一个步骤中扩展所有别名(主要来自FooTypeAlias |= String with Tagged[Foo] )或不扩展任何内容。 因此,当它比较String @@ FooA @@ B它不会展开,因为它们按原样匹配。 但是,当它比较FooTypeAliasA @@ B它完全扩张都与它的情况下有比较精致的类型,其中一个包含类型变量(见我的最终答案到其他相关的问题)。 在这里,我们精心设计的抽象再次破裂,约束的顺序开始变得重要。 你作为程序员, A with Tagged[B] <:< String with Tagged[Foo]查看A with Tagged[B] <:< String with Tagged[Foo]知道最佳匹配是A =:= StringB =:= Foo 然而,Scala将首先比较A <:< StringA <:< Tagged[Foo] ,并得出A <:< Tagged[Foo] with String (是的,反过来),它为B留下了Nothing 但是等等,我们需要一个隐式Decoder[A] - 它让我们循环。 所以A过度约束而B受到限制。

编辑:如果我们制作@@ abstract以防止编译器脱离,似乎有效: milessabin / shapeless#807 但现在它是盒子,我无法使阵列工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM