2011-07-22 9 views
3

このScalaコードが型チェックに失敗するのはなぜですか?これらの型引数が型の細分化に適合しないのはなぜですか?

trait T { type A } 
trait GenFoo[A0, S <: T { type A = A0 }] 
trait Foo[S <: T] extends GenFoo[S#A, S] 

"型引数[S#A、S]はGenFooの型パラメータの境界を形質に適合していない[A0、S <:T {タイプA = A0を}]" なぜ私は理解していません。回避策はありますか?

編集:指摘したように、適合エラーは、S <: T{type A = S#A}の検証失敗に起因します。ダニエルソブラルは私たちに伝えている、-explaintypes指さ:

S <: T{type A = S#A}? 
    S <: T? 
    true 
    S specializes type A? 
    this.A = this.A? 
     S = this.type? 
     false 
    false 
    false 
false 

私はこれを解釈するかどうかはわかりません。我々が定義しようとした場合、我々は違法循環参照を取得

注意、

trait Foo[S <: T { type A = S#A } ] extends GenFoo[S#A, S] 

ここで型改良は、新しい情報を追加していないようですが。 (またWhy is this cyclic reference with a type projection illegal?参照)

私のモチベーションはのように、S#Aに特化した特性Foo[S <: T]作成することです。この作業を取得するにはHow to specialize on a type projection in Scala?を、私は、実装トレイトGenFooに明示的なパラメータA0としてS#A表面化しようとしていますそれは直接専門化することができます。私はMiles Sabinの答えから型式改良アイデアをWhy is this cyclic reference with a type projection illegal?に適用したいと考えていましたが、私はこの適合エラーに遭遇します。

+0

-explaintypesを試しましたか? –

+0

ポインタをありがとう。 -explaintypesからの出力を含めるように質問を更新しました。 –

答えて

1

これが答えのようだ:

SはタイプAを専門と?

質問について専門はここから来ている:T { type A = A0 }。これはタイプTで、type Aに特化されています。つまり、元のTよりも制限されています。

その答えはいいえ - Sには特殊化するという制約はありません。

+0

「S <:T」と「S <:T {type A = S#A}」に違いがあることは驚きです。後者は特殊化されていますが、この専門化は「S」に追加の制約を追加していないようです。おそらく私は型の意味を誤解しているかもしれませんが、これはScala型の基本的ではなく実用的な制限であると思われます(おそらく、後者は、それを直接使用しようとすると、システム? –

1

タイプ制約に従うためには、ST { type A = A0 }のサブタイプでなければなりませんが、サブタイプはTです。

+0

しかしこの場合は 'A0 = S#A'なので、' S <:T {type A = S#A} ' –

1

私はこの話題の専門家ではなく、あなたのコードで遊んだところ、問題はS#Aの部分ではなく、Sの部分であることがわかりました。

あなたは、このようなコードを記述する場合:

trait T { type A } 
trait GenFoo[A0, S <: T] // the { type A = A0 } part is not there anymore 
trait Foo[S <: T] extends GenFoo[S#A, S] 

Foo[S <: T]SGenFoo[A0, S <: T]Sに準拠しているため、それは、コンパイルされます。

あなたの例では、コンパイラはSTのサブタイプであるため、type Aが定義されていることを知っているが、それはそれはSAS#Aであることを確認することができますポイントに付属していません。

+0

ありがとうございます。この情報を含めるように質問を更新しました。 –

関連する問題