I would like to call 'contains' on my Iterables :-)
The reason Iterable
does not have a contains
method is because the way it is defined can have direct consequences on variance. Basically, there are two type signatures that make sense for it:
def contains(v: Any): Boolean
def contains(v: A): Boolean
The second definition has increased type safety. However, A
, which is the type parameter of collection, appears in a contra-variant position, which forces the collection to be invariant. It could be defined like this:
def contains[B >: A](v: B): Boolean
but that wouldn't offer any improvement over the first signature, using Any
.
As a consequence of this, you'll see that immutable.Seq
is co-variant and uses the first signature, while immutable.Set
is invariant and uses the second signature.
A1
will be inferred to be the common supertype. And because everything is descendant from Any
, then all types have a common supertype with each other. –
Gorky Any
, as you write, then? –
Tend I don't know why contains
is not defined on Iterable
or TraversableOnce
, but you could easily define it yourself:
class TraversableWithContains[A](underlying: TraversableOnce[A]) {
def contains(v: Any): Boolean =
underlying.exists(_ == v)
}
implicit def addContains[A](i: Iterable[A]) = new TraversableWithContains(i)
and use it as if it were defined on Iterable:
val iterable: Iterable[Int] = 1 to 4
assert(iterable.contains(3))
assert(!iterable.contains(5))
© 2022 - 2024 — McMap. All rights reserved.
contains
is implemented using the signaturecontains[A1 >: A](elem: A1)
inSeqLike
(at least in Scala 2.11.8). I do not think this is the same as usingAny
- it places some constraints on theB
type - you can passAny
, but you cannot pass a type which is known to be unrelated. – Tend