Home > Enterprise >  Why is `contains` on collections not requiring the correct type?
Why is `contains` on collections not requiring the correct type?

Time:10-15

How come this compiles:

scala> val x: Vector[Int] = Vector(1,2,3)
val x: Vector[Int] = Vector(1, 2, 3)

scala> x.contains("hello")
val res4: Boolean = false

scala> x.contains(List(Map("anything" -> 3.14)))                                                 
val res5: Boolean = false

EDIT:

This is separate from this other question in which the element type of the collection is inferred (to Any) whereas here it is explicitly set (to Int).

CodePudding user response:

The signature is (in 3.0.0; I recommend always including the language/library version in such questions, and for Scala in particular)

def contains[A1 >: A](elem: A1): Boolean

This means that the argument type must be a supertype of Int, and "hello" is inferred to be Any which is indeed such a supertype.

The reason for the signature instead of maybe more expected

def contains(elem: A): Boolean

is that that signature wouldn't allow Vector and other collections to be covariant.

Specifically, if a Vector[Int] extends Vector[Any], and you can call contains(Any) on a Vector[Any], you must also be able to call it on a Vector[Int].

  • Related