为什么这个带有类型投影的循环引用是非法的? [英] Why is this cyclic reference with a type projection illegal?

查看:28
本文介绍了为什么这个带有类型投影的循环引用是非法的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The following pseudo-Scala yields an "illegal cyclic reference" error:

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

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

Questions: Why is this illegal? Is there a fundamental problem with soundness, or is it a limitation of the Scala type system? Is there a work-around?

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

My intent is to create a trait T with a type member A that can be lifted on demand to a type parameter via the super-trait GenT[A]. One application might be the expression of constraints, for example

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

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

This could be used as if it were def foo[S1 <: T, S2 <:T] ... with the constraint that S1#A == S2#A.

如果该技术可行,它也可能有助于解决以下问题:如何专注于 Scala 中的类型投影?

If the technique were possible, it might also help for the question: How to specialize on a type projection in Scala?

注意:我可以在任何地方使用 GenT 而不是 T,但我试图避免这种情况,因为它会导致大量类型参数分布在我的所有代码中传染性".

Note: I could use GenT instead of T everywhere, but I'm trying to avoid that because it would cause lots of type parameters to spread across all my code "infectiously".

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

The two questions below seem similar but are about a different type of cyclic reference:

推荐答案

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

In your initial example you can break the cycle by introducing an auxiliary type inbetween GenT[A] and T,

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

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

But from your motivating example I don't think you need to go down this route. The constraint you're after can be expressed directly using a refinement,

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

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

Also bear in mind that you can surface a type member as a type parameter via a type alias,

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

这篇关于为什么这个带有类型投影的循环引用是非法的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆