为什么这个Scala代码无法进行类型检查?
trait T { type A }
trait GenFoo[A0, S <: T { type A = A0 }]
trait Foo[S <: T] extends GenFoo[S#A, S]
我不明白为什么“类型参数[S#A,S]不符合特性GenFoo的类型参数界限[A0,S&lt;:T {type A = A0}]”。有解决办法吗?
编辑:正如已经指出的那样,一致性错误源于无法验证S <: T{type A = S#A}
。 Daniel Sobral指出-explaintypes
,它告诉我们:
S <: T{type A = S#A}?
S <: T?
true
S specializes type A?
this.A = this.A?
S = this.type?
false
false
false
false
我不确定如何解释这个。
请注意,如果我们尝试定义
,我们会得到非法的循环引用trait Foo[S <: T { type A = S#A } ] extends GenFoo[S#A, S]
虽然这里的类型细化似乎没有添加任何新信息。 (另见Why is this cyclic reference with a type projection illegal?)
我的动机是创建一个专注于Foo[S <: T]
的特质S#A
,如:How to specialize on a type projection in Scala?为了实现这一点,我试图将S#A
表示为实现特征A0
中的显式参数GenFoo
,可以直接使用。我希望将Miles Sabin的答案应用于Why is this cyclic reference with a type projection illegal?,但我遇到了这种一致性错误。
答案 0 :(得分:1)
为了符合类型约束,S
必须是T { type A = A0 }
的子类型,但它只是T
的子类型。
答案 1 :(得分:1)
我不是这方面的专家,我只是玩了你的代码,发现问题不是S#A
部分,而是S
部分。
如果您编写如下代码:
trait T { type A }
trait GenFoo[A0, S <: T] // the { type A = A0 } part is not there anymore
trait Foo[S <: T] extends GenFoo[S#A, S]
然后进行编译,因为S
中的Foo[S <: T]
符合S
中的GenFoo[A0, S <: T]
。
在您的示例中,编译器知道S
是T
的子类型,因此定义了type A
,但它没有达到这一点,它可以验证A
中的S
是S#A
。
答案 2 :(得分:1)
这似乎就是答案:
S专门打字A?
关于 specialize 的问题来自:T { type A = A0 }
。这是T
类型type A
专门的 - 意味着它比原始T
更受限制。
这个问题的答案是否定的 - S
没有约束它是专门的。