I have 3 traits
trait A
trait B
trait AB extends A with B
and a method
def collect[E: Manifest](list: List[Any]) =
list flatMap {
case record: E => Some(record)
case _ => None
}
For the given list
val list = new A {} :: new A {} :: new A with B {} :: new AB {} :: Nil
I invoked collect with different types
collect[A with B](list) // collect all elements from the list
collect[AB](list) // collect only the last element
Could anyone explain the difference in behavior for A with B and AB types?
It is highly unintuitive but it conforms to the specification. First, quoting from the Manifest docs (emphasis mine):
So in
collect[A with B]we are matching the erasure ofA with B. And what is that? if we look at the Type erasure section of the spec, we read:and the intersection dominator is defined as (again, emphasis mine)
In our case the subsequence is
A,Bas they don't have any subtyping relationship, and thus the erasure ofA with BisA, so that incollect[A with B]we are actually matchingA.You can easily see this behavior by looking at the output of
collect[B with A], and/or adding anew B {}to yourlist.