为什么这些类型参数不符合类型细化?
为什么此 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 <: 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]
尽管这里的类型细化似乎没有添加任何新信息。 (另请参见为什么这个循环引用带有类型投影非法?)
我的动机是创建一个专门针对 S#A
的特征 Foo[S <: T]
,如:如何在 Scala 中专门研究类型投影?为了实现这一点,我尝试将 S#A
作为实现特征 GenFoo
中的显式参数 A0
来显示,它可以直接专门化。我希望将迈尔斯·萨宾 (Miles Sabin) 的答案中的类型细化思想应用到
Why does this Scala code fail to typecheck?
trait T { type A }
trait GenFoo[A0, S <: T { type A = A0 }]
trait Foo[S <: T] extends GenFoo[S#A, S]
I don't understand why "type arguments [S#A,S] do not conform to trait GenFoo's type parameter bounds [A0,S <: T{type A = A0}]". Is there a work-around?
Edit: As has been pointed out, the conformance error stems from the failure to verify S <: T{type A = S#A}
. Daniel Sobral pointed to -explaintypes
, which tells us:
S <: T{type A = S#A}?
S <: T?
true
S specializes type A?
this.A = this.A?
S = this.type?
false
false
false
false
I'm not sure how to interpret this.
Note that we get an illegal cyclic reference if we try to define,
trait Foo[S <: T { type A = S#A } ] extends GenFoo[S#A, S]
although the type refinement here doesn't seem to add any new information. (See also Why is this cyclic reference with a type projection illegal?)
My motivation is to create a trait Foo[S <: T]
that specializes on S#A
, as in: How to specialize on a type projection in Scala? To get this to work, I'm trying to surface S#A
as an explicit parameter A0
in the implementation trait GenFoo
, which can be specialized directly. I was hoping to apply the type refinement idea from Miles Sabin's answer to Why is this cyclic reference with a type projection illegal? but I run into this conformance error.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这似乎就是答案:
关于专业化的问题来自这里:
T { type A = A0 }
。这是类型T
和A 类型
专用 - 意思是,它比原始T
受到更多限制。这个问题的答案是否定的——
S
没有任何特殊化的限制。This seems to be the answer:
The question about specialize comes from here:
T { type A = A0 }
. This is the typeT
withtype A
specialized -- meaning, it is more restricted than the originalT
.The answer to that question is no -- there's no constrains on
S
that it be specialized.为了符合类型约束,
S
必须是T { type A = A0 }
的子类型,但它只是T 的子类型
。In order to conform to the type constraints,
S
would have to be a subtype ofT { type A = A0 }
, but it is only a subtype ofT
.我不是这个主题的专家,我只是玩了一下你的代码,发现问题不是
S#A
部分,而是S
部分。如果你这样写代码:
那么它会编译,因为
Foo[S <: T]
中的S
符合S
中的S
代码>GenFoo[A0, S <: T]。在您的示例中,编译器知道
S
是T
的子类型,因此定义了type A
,但它没有达到目的,它可以验证S
中的A
是S#A
。I'm not an expert on this topic, I just played around with your code and found out that the problem is not the
S#A
part, but theS
part.If you write the code like this:
then it compiles, because
S
inFoo[S <: T]
conforms to theS
inGenFoo[A0, S <: T]
.In your example the compiler knows that
S
is a subtype ofT
and therefore has thetype A
defined, but it does not come to the point, where it can verify that theA
inS
is theS#A
.