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

0__*_*0__ 8 types scala 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 }
Run Code Online (Sandbox Code Playgroud)

错误如下:

error: overriding type Peer in trait Fenced with bounds >: Nothing <: Sys[this.Peer];
 type Peer has incompatible type
       def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer }
                                                      ^
Run Code Online (Sandbox Code Playgroud)

为什么?(也试图自我类型添加_:S =>Sys,没有问题)


虽然Rex的答案使得构造Fenced对象成为可能,但它并没有真正解决我在使用类型投影(S#Peer)时表示类型字符丢失的问题.我想出了另一种造成更严格限制的情景; 我认为这是核心问题:

trait Test[S <: Sys[S]] {
  def make[T <: Sys[T]](): Unit

  make[S#Peer]()
}

error: type arguments [S#Peer] do not conform to method make's type 
       parameter bounds [T <: Sys[T]]
              make[S#Peer]()
                  ^
Run Code Online (Sandbox Code Playgroud)

Rex*_*err 3

我仍然不完全确定您正在寻找什么约束,但这是一种可能性:

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 }
Run Code Online (Sandbox Code Playgroud)

这使您(并且需要!)可以Peer访问Fenced. 我不确定是否Fenced可以这样做,或者是否必须跨外部类型进行抽象。