如何解决我怎样才能阻止 Scala 用它自己来满足这个隐式的参数,即使它是一个不同的类型?
我正在尝试制作一个通用解码器,根据在这些字段上声明的 shapeless.Tag
对字段进行不同的解码。为此,我有一个隐式定义如下,它可以将 B
的任何解码器转换为 B @@ Id
的解码器(A
是输入类型)。
implicit def idTagDecoder[A,B](implicit dec: Lazy[Decoder[A,B]]): Decoder[A,B @@ Id] =
dec.value.decode(a).map(tag[Id](_))
当我运行测试并使用由此生成的 Decoder
时,我得到一个 StackOverflowError
,表明 Scala 使用生成的解码器满足 dec
参数!如果我不使用 Lazy
,则不会发生这种情况,但我会得到“发散的隐式扩展”。
所以,我修改了代码只是为了确保这是正在发生的事情。现在,我的定义是这样的。
implicit def idTagDecoder[A,B @@ Id] =
new Decoder[A,B @@ Id] {
override def decode(a: A): DecodeResult[B @@ Id] = {
// These are different types,so the compiler shouldn't try to satisfy `dec` with `this`,but it does!
require(dec.value != this)
dec.value.decode(a).map(tag[Id](_))
}
}
正如预期的那样,这在运行时给了我一个“需求失败”。
编译器比这更清楚。如果我尝试执行它正在执行的显式操作以生成 Decoder[JAny,UUID @@ Id]
,它会知道这是错误的类型并且无法编译。
val d: Decoder[JAny,UUID @@ Id] = Id.idTagDecoder(Lazy(Id.idTagDecoder(Decoder.uuidDecoder)))
这在某种程度上是预期的行为吗?如果是这样,我应该如何做我想做的事?如果没有,有人知道如何解决这个问题吗?
我试图得到一个演示这个问题的小例子无济于事。它的工作原理就像我期望的任何比我的用例更简单的东西。您可以查看代码并运行失败的测试 here(使用 sbt test
)。
我使用的是 shapeless 2.3.3 和 Scala 2.12.13。
谢谢!
更新:鉴于这看起来像是 Scala 编译器中的一个错误,我继续针对 Scala 2.13.5 对其进行了测试,但问题仍然存在。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。