2016-05-26 14 views
0

私には分かりませんが、Scalaコンパイラのエラーパズルがあります。ここに与えられていない理由で、私はcuriously recurring template patternを使ってクラスを宣言する必要があります。私のクラスの中には、他のクラスをパラメータとして含む必要があります。たとえば、私のコードを削除したバージョンは、次のようになります。Scalaの抽象型で奇妙に繰り返されるテンプレートパターンの制約

trait Container[C <: Container[C]] { 
    def stuff: C 
} 

trait Aggregation { 
    def fill(x: Double): Unit 
} 

class Counted extends Container[Counted] { 
    def stuff = this 
} 

class Counting extends Container[Counting] with Aggregation { 
    def stuff = this 
    def fill(x: Double) { } 
} 

class Binned[V <: Container[V]](v: V) extends Container[Binned[V]] { 
    def stuff = this 
    def substuff = v 
} 

class Binning[V <: Container[V] with Aggregation](v: V) extends Container[Binning[V]] with Aggregation { 
    def stuff = this 
    def substuff = v 
    def fill(x: Double) { } 
} 

上記の動作は問題ありません。

trait Container[C <: Container[C]] { 
    type Ed <: Container[Ed] 
    def stuff: C 
} 

trait Aggregation { 
    def fill(x: Double): Unit 
} 

class Counted extends Container[Counted] { 
    type Ed = Counted 
    def stuff = this 
} 

class Counting extends Container[Counting] with Aggregation { 
    type Ed = Counted 
    def stuff = this 
    def fill(x: Double) { } 
} 

class Binned[V <: Container[V]](v: V) extends Container[Binned[V]] { 
    type Ed = Binned[V] 
    def stuff = this 
    def substuff = v 
} 

class Binning[V <: Container[V] with Aggregation](v: V) extends Container[Binning[V]] with Aggregation { 
    type Ed = Binned[V#Ed] 
    def stuff = this 
    def substuff = v 
    def fill(x: Double) { } 
} 

を、コンパイラがEdは明らかに、すべてのContainersため<: Container[Ed]あるとき私

<console>:34: error: type arguments [V#Ed] do not conform to class Binned's type parameter bounds [V <: Container[V]] 
      type Ed = Binned[V#Ed] 

に伝えるために神経を持っている:今、私はそれぞれ各-edに-ingから抽象型を追加します。

厳密に言えば、タイプEdContainers with Aggregationにのみ必要です。移動すると同じエラーが発生します。

私の意図をどのようにコンパイラに伝えることができるのか誰も知っていますか?

答えて

1
class Binning[V <: Container[V] with Aggregation](val v: V) extends Container[Binning[V]] with Aggregation { 
    type Ed = Binned[v.Ed] 
    def stuff = this 
    def substuff = v 
    def fill(x: Double) { } 
} 

作品。しかし、あなたのバージョンがコンパイルされているように思えます。

+0

ありがとう、素晴らしい、素晴らしい!私はこのような明らかな解決策のために額に自分自身を叩いていますが、どちらもうまくいくはずです。 –

+0

'v'がプライベートであるときに' v.Ed'を参照することはできないので、引数リストの 'val'が必要になることを指摘する価値があります。私のユースケースでは、「v」を公開したいので、すべてうまくいきます。 –

+0

私はあなたがこれについての答えを得ていない場合、なぜ 'V#Ed'がscala-userメーリングリストでコンパイルされないのかを尋ねることを勧めます。 –

関連する問題