何が機能するか(パートA)
タイプパラメータを持つトレイトがあるとします。
trait A[T]
実存型を使用してA
、すべて同じであるsのコレクションを取得するメソッドを作成できT
ます。
def foo(as: Seq[A[X]] forSome { type X }) = true
これは以下とは異なることに注意してください。
def otherFoo(as: Seq[A[X] forSome { type X }]) = true
または同等のもの:
def otherFoo(as: Seq[A[_]]) = true
これらの場合、実存の範囲はの内部にあるSeq
ため、A
sは異なるT
sを持つことができます。私のオリジナルfoo
(実存的なスコーピングを使用Seq
)では、次のように問題ありません。
foo(Seq(new A[Int] {}, new A[Int] {}))
ただし、型パラメーターを異なるものにすると、コンパイルされません。
scala> foo(Seq(new A[Int] {}, new A[String] {}))
<console>:10: error: type mismatch;
found : Seq[A[_ >: java.lang.String with Int]]
required: Seq[A[X]] forSome { type X }
foo(Seq(new A[Int] {}, new A[String] {}))
^
これはすべて非常に簡単です。
何が機能するか(パートB)
ここで、型パラメーターの代わりに型メンバーを持つ同様の特性があるとします。
trait B { type T }
B
私はいくつかの指定されたものだけを取るメソッドを書くことができますT
:
scala> def bar[X](b: B { type T = X }) = true
bar: [X](b: B{type T = X})Boolean
scala> bar[Int](new B { type T = Int })
res5: Boolean = true
scala> bar[String](new B { type T = Int })
<console>:10: error: type mismatch;
found : java.lang.Object with B
required: B{type T = String}
bar[String](new B { type T = Int })
^
繰り返しますが、これは期待どおりに機能します。
動作しないもの
上記と同等のものを書き込もうとするとfoo
、タイプメンバーの場合、状況がおかしくなります。
scala> def baz(bs: Seq[B { type T = X }] forSome { type X }) = true
baz: (as: Seq[B{type T = X}] forSome { type X })Boolean
scala> baz(Seq(new B { type T = Int }, new B { type T = String }))
res7: Boolean = true
最後の行がコンパイルされることは私には意味がありません。すべてのタイプメンバーを同じにしたいと言った。私foo
は、型パラメーターに対してこれを実行できることをbar
示し、型メンバーに基づいて型を制約できることを示しています。しかし、私は2つを組み合わせることができません。
私はこれを2.9.2と2.10.0-M5で試しました。
動機
この質問はこれに触発されており、私の最初の考えは、実存型を使用することでした(繰り返しパラメータの型のスコープに実存型を取得することは不可能であると思われるという問題を2番目に取っておきます)。ここで便利です):
def accept(rs: Seq[RList[Int] { type S = X }] forSome { type X }) = true
ただし、これは実際には機能しません。上記の簡略化された例と同じ奇妙な結果が得られます。