Подтвердить что ты не робот

Scala: Почему Seq.contains принимает любой аргумент, а не аргумент типа последовательности?

Так, например, почему List(1,2,3,4).contains("wtf") даже компилируется? Было бы неплохо, если бы компилятор отказался от этого?

4b9b3361

Ответ 1

Множество интересных ответов, но вот моя собственная теория: если contains не получил Any, то Seq не мог быть ковариантным.

См., например, Set, который не является ковариантным и contains принимает A вместо Any.

Причины этого оставлены как упражнение для читателя.;-) Но вот подсказка:

scala> class Container[+A](elements: A*) {                         
     |   def contains(what: A): Boolean = elements exists (what ==)
     | }
<console>:7: error: covariant type A occurs in contravariant position in type A of value what
         def contains(what: A): Boolean = elements exists (what ==)
                      ^

Ответ 2

"содержит" в основном о тестировании равенства, а равенство в Scala (как и в Java перед ним) является нетипизированным. Практическая ценность наличия нетипизированного равенства мала, но не равна нулю. Есть, например, несколько случаев, когда имеет смысл, чтобы два объекта разных классов были равны друг другу. Например, вы можете пожелать, чтобы объект типа RGBColor был равен PantoneColor, если они определяют один и тот же оттенок, или неизменяемый HashSet и неизменяемый TreeSet равны, если они содержат одни и те же элементы. Тем не менее, нетипизированное равенство также вызывает кучу головных болей, и тот факт, что компилятор может легко поймать, что List(1,2,3,4).contains("wtf") является бессмысленным, но не является одним из них.

Большинство инструментов поиска ошибок Java включают тесты для обнаружения присутствия невероятных применений без аутентификации. (Я написал проверки для этого в IntelliJ IDEA.) Я не сомневаюсь, что когда инструменты поиска ошибок Scala заходят онлайн, они будут среди первых обнаруженных ошибок.

Ответ 3

SeqLike.contains проверяет, присутствует ли значение, проверяя элемент в последовательности, которая равна значению (с использованием ==). == принимает Any, поэтому я подозреваю, что это причина.