As a rule, when collecting all elements of a sequence corresponding to a particular type, the resulting set 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 input type is parameterized by the limited element type, and all I want back is a sequence parameterized by the associated type (not a 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 really want to return the sequence parameterized by the element 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 restore functionality, I can include a member type in the call collect, but this seems superfluous, given that each element must match this 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}
}
, , collect ed?