【问题标题】:Why is this cyclic reference with a type projection illegal?为什么这个带有类型投影的循环引用是非法的?
【发布时间】:2011-10-06 21:12:06
【问题描述】:

以下伪 Scala 产生“非法循环引用”错误:

trait GenT[A]
trait T extends GenT[T#A] {
  type A
}

问题:为什么这是非法的?健全性是否存在根本问题,还是 Scala 类型系统的限制?有解决办法吗?

我的意图是创建一个带有类型成员A 的特征T,可以通过超特征GenT[A] 按需提升为类型参数。一种应用可能是约束的表达,例如

def foo[A, S1 <: GenT[A], S2 <: GenT[A]] ...

这可以像 def foo[S1 &lt;: T, S2 &lt;:T] ... 一样使用,约束条件为 S1#A == S2#A

如果该技术可行,它也可能有助于解决这个问题:How to specialize on a type projection in Scala?

注意:我可以在任何地方使用GenT 而不是T,但我会尽量避免这种情况,因为它会导致大量类型参数“感染性地”传播到我的所有代码中。

下面的两个问题看起来很相似,但是是关于不同类型的循环引用:

【问题讨论】:

    标签: scala types


    【解决方案1】:

    在您的初始示例中,您可以通过在 GenT[A] 和 T 之间引入辅助类型来打破循环,

    trait GenT[A]
    trait TAux { type A }
    trait T extends TAux with GenT[TAux#A]
    

    但是从你的激励例子来看,我认为你不需要走这条路。您所追求的约束可以直接使用细化来表达,

    trait T { type A }
    def foo[A0, S1 <: T { type A = A0 }, S2 <: T { type A = A0 }] ...
    

    还请记住,您可以通过类型别名将类型成员作为类型参数显示,

    trait T { type A }
    type TParam[A0] = T { type A = A0 }
    def foo[A0, S1 <: TParam[A0], S2 <: TParam[A0]] ...
    

    【讨论】:

    • 很棒的信息,谢谢!我确实在尝试显示类型成员。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多