Scala 无法将表示类型实现为类型成员

Scala 无法将表示类型实现为类型成员,scala,types,abstract-type,type-projection,bounded-quantification,Scala,Types,Abstract Type,Type Projection,Bounded Quantification,当我回头时,我遇到了不同的谜语,这些谜语似乎是相关的。这是其中之一: trait Sys[S <: Sys[S]] { type Peer <: Sys[Peer] } trait Fenced { type Peer <: Sys[Peer] } def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer } 我仍然不能完全确定您要寻找的约束条件,但有一种可能性: trait Sys[S <

当我回头时,我遇到了不同的谜语,这些谜语似乎是相关的。这是其中之一:

trait Sys[S <: Sys[S]] {
  type Peer <: Sys[Peer]
}

trait Fenced {
  type Peer <: Sys[Peer]
}

def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer }

我仍然不能完全确定您要寻找的约束条件,但有一种可能性:

trait Sys[S <: Sys[S]] {
  type Peer <: Sys[Peer]
}

trait Fenced {
  type MySys <: Sys[MySys]
  type Peer = MySys#Peer
}

def makeFence[S <: Sys[S]] = new Fenced{ type MySys = S }

trait Sys[S您能使
Sys
的类型参数协变吗?例如,它编译:

trait Sys[+S <: Sys[S]] { type Peer <: Sys[Peer] }
trait Fenced { type Peer <: Sys[Peer] }

def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer }
正如我所期望的那样:

scala> val fenceX = makeFence[SysX]
fenceX: java.lang.Object with Fenced{type Peer = Example.SysX#Peer} = ...

scala> val y: fenceX.Peer = SysY(1)
y: fenceX.Peer = SysY(1)

scala> val y: fenceX.Peer = SysX(1)
<console>:15: error: type mismatch;
 found   : Example.SysX
 required: fenceX.Peer
       val y: fenceX.Peer = SysX(1)
scala>val fenceX=makeFence[SysX]
fenceX:java.lang.Object与Fenced{type Peer=Example.SysX#Peer}=。。。
scala>valy:fenceX.Peer=SysY(1)
y:fenceX.Peer=SysY(1)
scala>valy:fenceX.Peer=SysX(1)
:15:错误:类型不匹配;
找到:Example.SysX
必需:fenceX.Peer
valy:fenceX.Peer=SysX(1)

(我认为)哪一个是你想要的?

我认为根本问题是
特征A[B你试图实现什么?
S#Peer
Peer
来自
S
,但是
围栏
希望Peer是它的
Peer
而不是
S
,这产生了(表面层)不兼容。我想它在逻辑上是否不兼容取决于您是将类型视为简单别名还是所有权声明。不幸的是,Scala在这方面并不完全一致。您只是想说“
Fenced
的类型是
Sys
”?@RexKerr-如果目的不明确,很抱歉。链接的问题给出了整个上下文。基本上,我(认为我)的意思需要定义两个链接系统,一个被另一个引用,以允许我在外部系统中传递,除了
S对不起,特拉维斯,没有其他信息,但是
S
必须保持不变:-(@Travis Hi-Travis。我不完全理解为什么这个问题不起作用,但我正在努力学习。你能解释一下为什么它在它的共变量时起作用,而在它的不变量时不起作用吗?非常有趣的方法,将类型参数移动到类型成员中。是的,在
Fenced
中使用这两种类型没有问题。我必须玩这个游戏通过所有的后果,但至少这对我来说是一个新的想法,谢谢!这只适用于
Sys
上的不变
S
,因为它会删除
对等点,这并不是说这不是一个有效的解决方法,但一般来说,如果你有
val f=makeFence[X]
通过这种方法,不会出现
f.Peer@TravisBrown-同意,我假设
S
应该是不变的。此外,尽管能够创建不适合居住的类型令人失望,因为您无法创建完全实现的类型,而这些类型不符合
f.Peer@RexKerr的要求。谢谢您的回答。但是,您能提出建议吗est为什么原来的问题不起作用,而这个问题起作用了。它们不是一样吗(除了明显地使其成为成员之外)?
trait Sys[+S <: Sys[S]] { type Peer <: Sys[Peer] }
trait Fenced { type Peer <: Sys[Peer] }

def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer }
object Example {
  case class SysX(i: Int) extends Sys[SysX] { type Peer = SysY }
  case class SysY(j: Int) extends Sys[SysY] { type Peer = SysX }
}

import Example._
scala> val fenceX = makeFence[SysX]
fenceX: java.lang.Object with Fenced{type Peer = Example.SysX#Peer} = ...

scala> val y: fenceX.Peer = SysY(1)
y: fenceX.Peer = SysY(1)

scala> val y: fenceX.Peer = SysX(1)
<console>:15: error: type mismatch;
 found   : Example.SysX
 required: fenceX.Peer
       val y: fenceX.Peer = SysX(1)