gpt4 book ai didi

Scala:带类型参数的类的隐式证据

转载 作者:行者123 更新时间:2023-12-04 03:29:35 24 4
gpt4 key购买 nike

这是一个简单的设置,具有两个特征,一个类的协变量类型参数受以前的特征限制,第二个类的类型参数受另一个类限制。对于这两个类,仅当两个特征之一作为类型参数的基础时,一种特定的方法(通过隐式证据)才可用。这样编译就可以了:

trait Foo
trait ReadableFoo extends Foo {def field: Int}

case class Bar[+F <: Foo](foo: F) {
def readField(implicit evidence: F <:< ReadableFoo) = foo.field
}

case class Grill[+F <: Foo, +B <: Bar[F]](bar: B) {
def readField(implicit evidence: F <:< ReadableFoo) = bar.readField
}

但是,由于 BarF中是协变的,所以我不需要在 F中使用 Grill参数。我只需要 BBar[ReadableFoo]的子类型。但是,这失败了:
case class Grill[+B <: Bar[_]](bar: B) {
def readField(implicit evidence: B <:< Bar[ReadableFoo]) = bar.readField
}

与错误:
error: Cannot prove that Any <:< this.ReadableFoo.
def readField(implicit evidence: B <:< Bar[ReadableFoo]) = bar.readField

为什么不考虑隐式证据?

最佳答案

调用bar.readField是可能的,因为证据实例<:<允许从BBar[ReadableFoo]的隐式转换。

我认为要调用readField,您需要一个连续的证据参数F <:< ReadableFoo的问题。因此,我的猜测是,编译器没有在隐式解析的第一个搜索阶段完全替换Bar的类型参数(因为要找到readField,因此它只需要任何Bar即可)。然后它阻塞了第二个隐式分辨率,因为据我所知,没有任何形式的“回溯”。

反正。好处是,您不仅了解编译器,而且可以使用apply<:<方法或使用辅助方法implicitly显式地进行转换:

case class Grill[+B <: Bar[_]](bar: B) {
def readField(implicit evidence: B <:< Bar[ReadableFoo]) = evidence(bar).readField
}

case class Grill[+B <: Bar[_]](bar: B) {
def readField(implicit evidence: B <:< Bar[ReadableFoo]) =
implicitly[Bar[ReadableFoo]](bar).readField
}

还有另一种可能是最干净的可能性,因为它不依赖于 <:<的实现,这可能是@Kaito建议的问题:
case class Grill[+B <: Bar[_]](bar: B) {
def readField(implicit evidence: B <:< Bar[ReadableFoo]) =
(bar: Bar[ReadableFoo]).readField
}

关于Scala:带类型参数的类的隐式证据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11284538/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com