両方のクラスを制御でき、共変フィルタリングが必要であると仮定して、それらのオブジェクトの型パラメーターに基づいてオブジェクトのコレクションをフィルター処理する最良の方法は何ですか?
正しく機能しないコードは次のとおりです。
trait Foo
case class Foo1() extends Foo
trait ReadableFoo extends Foo {def field: Int}
case class Foo2(field: Int, flag: Boolean) extends ReadableFoo
case class Foo3(field: Int, name: String) extends ReadableFoo
case class Bar[+F <: Foo](foo: F)
val seq = Seq(
Bar[Foo1](Foo1()),
Bar[Foo2](Foo2(1,true)),
Bar[Foo3](Foo3(1,"Fooz"))
)
// Should keep one
val first = seq collect {case x: Bar[Foo2] => x}
// Should keep two
val both = seq collect {case x: Bar[ReadableFoo] => x}
これは、case x: Bar[Foo1]
型消去を介してcase x: Bar[_]
コンパイル後にに変換されるためです。この問題を解決するためにマニフェストを使用することができませんでした。memberType = F
メンバータイプ(つまり)を追加して、Bar
スイッチをオンにする方法はありcase x if (x.memberType <:< ReadableFoo) => x
ますか?
アップデート
0__は、元の問題に対する適切な解決策をすぐに見つけました。わずかな変更は、ケースクラスフィールド自体がコレクションである場合です。
case class Bar[+F <: Foo](foo: Seq[F])
val seq = Seq(
Bar[Foo1](Seq(Foo1())),
Bar[Foo2](Seq(Foo2(1,true))),
Bar[ReadableFoo](Seq(Foo2(1,true), Foo3(1,"Fooz")))
)
// Should keep one
val first = seq collect {case x: Bar[Foo2] => x}
// Should keep two
val both = seq collect {case x: Bar[ReadableFoo] => x}
Seq
が空である可能性があり、したがってテストする要素がないため、これが可能かどうかはわかりません。