Normally, when collecting all the elements of a sequence that match a particular type, the resulting collection has both the type of the original collection and the type selected for:
trait Foo
trait Bar
trait Baz {
// Works
def def1(foo: Seq[Foo]): Seq[Foo with Bar] =
foo collect {case foobar: Bar => foobar}
}
This even works when the the input type is parameterized by a bounded member type and all I want back is a sequence parameterized by the bound type (not the member type):
trait Baz {
type memberType <: Foo
// Works
def2(foo: Seq[memberType]): Seq[Foo with Bar] =
foo collect {case foobar: Bar => foobar}
}
However, this fails when I actually want back a sequence parameterized by the member type:
trait Baz {
type memberType <: Foo
// Fails
def def3(foo: Seq[memberType]): Seq[memberType with Bar] =
foo collect {case foobar: Bar => foobar}
}
Error message:
error: type mismatch;
found : Seq[this.Foo with this.Bar]
required: Seq[Baz.this.memberType with this.Bar]
foo collect {case foobar: Bar => foobar}
To recover functionality, I can include the member type in the collect
call, but that seems redundant given that every element has to match that type because of the signature:
trait Baz {
type memberType <: Foo
// Works
def def4(foo: Seq[memberType]): Seq[memberType with Bar] =
foo collect {case foobar: memberType with Bar => foobar}
}
Is there a way to define a sequence of member types so that they remember their member types when collect
ed?