2015-07-17 6 views
4

Так дали список:Почему Scala List [Int] .contains принимает параметр [Int]?

val a:List[Int] = List(1,2,3) 

Вы можете сделать:

a.contains(Option(2)) 

который возвращает ложь. Я понимаю, из следующих определений функций, что позволяет этому компилировать на все это было сделано с целью:

def contains[A1 >: A](elem : A1) : scala.Boolean = {...} 
sealed abstract class Option[+A]() ... 

То, что я не понимаю, почему - есть случай использования, где это полезно? Если он автоматически сглаживает опцию перед сравнением, поэтому приведенное выше значение возвращает true, тогда оно может быть полезно, но поскольку оно всегда будет возвращать false.

Я спрашиваю, потому что легко забыть разворачивать переменную Option, которую вы передаете в List.contains, что приводит к потенциально затруднению поиска ошибок.

Спасибо!

+1

Как указано, 'contains()' принимает любой тип arg. Чтобы сохранить безопасность типов, мы можем использовать 'exists()'. – jwvh

+0

Спасибо всем, просто для подведения итогов для других - существуют следующие 2 варианта для сохранения безопасности типа (т. Е. Оба не скомпилируются): 'a.contains [Int] (опция (2))' и 'a.exists (_ = = Option (2)) ' – JBY

ответ

4

Представьте себе следующее:

sealed trait Result 
case class SimpleResult(x: Int) extends Result 
case class FancyResult(x: Int, y: Int) extends Result 

val okResults: List[SimpleResult] = // ... 

def calcResult: Result = ??? 

okResults.contains(calcResult) 

Это тот случай, когда это полезно, что вы можете назвать contains с надтипом типа List.

В вашем случае происходит неприятный побочный эффект: Option[Int] не является супертипом Int. Однако у них есть общий супертип: Any. Таким образом, ваш призыв к contains получает вывод на:

a.contains[Any](Option(2)) 

Поскольку Option[Int] является подтипом Any, вы имеете право передать его contains. Вероятно, это то, чего вы не хотели бы в большинстве случаев, но трудно (невозможно?) Определить такой интерфейс в системе типов Scala.

+1

Опция [Int] не является супертипом Int, хотя – Cubic

+0

Да. Но 'Any' является супертипом' Int' и 'Option [Int]' является подтипом 'Any', поэтому вы можете передать его методу, который принимает' Any'. Пожалуйста, удалите downvotes. Возможность передать опцию [Int] 'является прямым следствием того, что подтипирование и' A1' не ограничены (поскольку нет разумной верхней границы). – gzm0

+0

«но трудно (невозможно?) Определить систему типов с подтипированием, которая мешает вам это делать». У вас может быть система с подтипированием, но без верхнего типа типа «Любые». –

Смежные вопросы