0

why is it that something like:

val map = Map(....)

List(1,2,3,4).contains(map)

or

List(1,2,3,4).contains("hello")

Are allowed to compile. I though scala was type safe.

Brian
  • 20,195
  • 6
  • 34
  • 55
MaatDeamon
  • 9,532
  • 9
  • 60
  • 127
  • 1
    This has been asked: [http://stackoverflow.com/questions/31466497/why-does-scala-listint-contains-accept-optionint] For type safety we can use type constraints `x.contains[Int](4)` or use `x.exists(_==4)`. – jwvh Jul 20 '15 at 22:09

1 Answers1

0

If we consult the scaladocs for List.contains, you will notice the following method signature:

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

Of particular interest is the type parameters, [A1 >: A] If we break this down, we get:

  • A, the type of the elements that the List contains
  • A1, the type of the element you are searching for in the List
  • >:, a symbol representing a lower bound

This should be interpreted that A1 is lower bounded by A, so A1 is either of type A or a more generic type. See http://www.scala-lang.org/old/node/137 for more information about lower type bounds.

You have a list of Int. You ask if the list contains a String. Since Any >: String and Any >: Int, the compiler doesn't complain. The same circumstances apply for the Map scenario.

Hugo Sereno Ferreira
  • 8,600
  • 7
  • 46
  • 92
Zeimyth
  • 1,389
  • 12
  • 19
  • 1
    `String >: Int` is not true, since `String` is not a supertype of `Int`. However, any `String` is also an `Any`, which is a supertype of `Int`, and so the compiler is deducing that you mean to call `contains[Any]`. You can even test this by explicitly providing the generic parameter to `contains`: `List(1).contains[String]("foo")` will fail, but `List(1).contains[Any]("foo")` will compile. – Ben Reich Jul 20 '15 at 23:11
  • What is the benefit of `A1 :> A` in this case? If it doesn't really add any type safety, would contains[Any] accomplish exactly the same thing, or is there some other use case that it supports? – Ren Jul 21 '15 at 00:06
  • @Ren It ultimately is because List is covariant in A. The full explanation is very mathy, but if you're interested types and why it has to be that way, check out http://stackoverflow.com/a/2078619/2643828. – Zeimyth Jul 21 '15 at 14:05