8

別の質問に頭を悩ませている間、私は関連しているように見えるさまざまななぞなぞに出くわしました。これはそれらの1つです:

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 }

エラーは次のとおりです。

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 }
                                                      ^

なんで?(セルフタイプ_: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]()
                  ^
4

2 に答える 2

3

あなたが探している制約はまだ完全にはわかりませんが、1つの可能性があります:

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 }

Peerこれにより、と 内の元の外部型の両方にアクセスできるようになります (そして必要です!) Fenced。これを行うことができるかどうFencedか、または外部の型を抽象化する必要があるかどうかはわかりません。

于 2012-09-25T21:32:05.730 に答える
3

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 }

ここで、次のものがあるとします (REPL のコピーと貼り付けの利便性のためだけにオブジェクトにラップされます)。

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)

あなたが欲しいものはどれですか?

于 2012-09-25T21:35:10.760 に答える