加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 解码无形标记类型

发布时间:2020-12-16 08:52:00 所属栏目:安全 来源:网络整理
导读:鉴于以下关于亚扪人: @ 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.
鉴于以下关于亚扪人:

@ 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.好吗?新闻是有一个部分修复在 this comment等待有人加强并制作PR(也许这就是你).我认为这是部分的,因为看起来它适用于特定的标签,但不适用于通用标签(我不是100%肯定).

你看到一个不同的隐式扩张的原因真的很有趣.编译器可以在一个步骤中扩展所有别名(主要来自FooTypeAlias | =带有Tagged [Foo]的String)或不扩展任何内容.因此,当它比较String @@ Foo和A @@ B时,它不会展开,因为它们按原样匹配.但是当它比较FooTypeAlias和A @@ B时,它会完全扩展,并且最终会在必须比较精炼类型的情况下,其中一个包含类型变量(请参阅我的answer到您的其他相关问题).在这里,我们精心设计的抽象再次崩溃,约束的顺序开始变得重要.你作为程序员,用标记[B]<:<查看A带有Tagged [Foo]的字符串知道最佳匹配是A =:= String和B =:= Foo.然而,Scala将首先比较A<:<字符串和A<:<标记[Foo]并得出结论A<:<使用String标记[Foo](是的,反之),为B留下Nothing但是等等,我们需要一个隐式解码器[A]! - 让我们循环播放.所以A过度约束而B受到限制. 编辑:如果我们制作@@ abstract以防止编译器进行deiasing:milessabin/shapeless#807似乎有效.但是现在它是盒子而我无法使数组工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读