Scala: if the collection type parameter survives “collect” when the type parameter is a member type

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?

+5
1

, - . :

trait Baz[A <: Foo] {
  def def3(foo: Seq[A]): Seq[A] =
    foo collect {case foobar => foobar}
}

:

trait Baz[A <: Foo] {
  def def3(foo: Seq[A]): Seq[A] =
    foo collect {case foobar: Bar => foobar}
}

:

trait Baz[A] {
  def def3(foo: Seq[A]): Seq[A] =
    foo collect {case foobar: Bar => foobar}
}

; , - collect . - , : -/

Kaito, , . ( ), (Foo) . , scala, - ...

+1

All Articles