为什么这些类型参数不符合类型细化?

时间:2011-07-22 20:17:36

标签: scala types specialization type-projection

为什么这个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?,但我遇到了这种一致性错误。

3 个答案:

答案 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]

在您的示例中,编译器知道ST的子类型,因此定义了type A,但它没有达到这一点,它可以验证A中的SS#A

答案 2 :(得分:1)

这似乎就是答案:

  

S专门打字A?

关于 specialize 的问题来自:T { type A = A0 }。这是T类型type A 专门的 - 意味着它比原始T更受限制。

这个问题的答案是否定的 - S没有约束它是专门的。