Как систематически избежать небезопасного сопоставления с образцом в Scala? - PullRequest
12 голосов
/ 18 января 2012

Рассмотрим следующую неработающую функцию:

def sum (list : Seq[Int]) : Int = list match {
  case Nil => 0
  case head :: tail => head + sum(tail)
}

Здесь функция должна была работать с List[Int], но вместо этого она была реорганизована для принятия Seq[Int], что приводило к поломке без уведомления компилятора.

Эта зияющая дыра в обнаружении неполного совпадения с образцом в Scala делает его почти бесполезным.

Я хочу иметь способ систематического выявления таких проблем.В частности, я бы хотел, чтобы компилятор выдавал ошибку / предупреждение при каждом сопоставлении с шаблоном instanceof, т. Е. Я хочу разрешать сопоставления с шаблоном только в закрытых иерархиях и в пользовательских сопоставлениях.

Существует ли существующий компиляторопции / плагины для проведения консервативных (в отличие от произвольных) проверок безопасности сопоставления с образцом?

Ответы [ 2 ]

3 голосов
/ 18 января 2012

Nil и :: - это явно способы построения List, но не все Seq значения оказываются Lists, поэтому можно ожидать, что средство проверки типа Scala отклонит эту программу как некорректно набранную,Правильно?

Неверно.Попробуйте это, и вы поймете, что я имею в виду:

def sum (list : Seq[Int]) : Int = list match {
  case Nil => 0
  case head :: tail => head + sum(tail)
  case _ => -1
}

> sum(Array(1,2,3).toSeq)
res1: Int = -1
> sum(List(1,2,3))
res2: Int = 6

Итак, вы видите, некоторые Seq uences могут быть в состоянии разобраться с Nil и ::, так что те, которые могут, будут.Те, кто не может, потерпят неудачу в сопоставлении с образцом и перейдут к следующему совпадению.Nil и :: достаточно, чтобы охватить все возможности для List, но не для Seq.Здесь есть компромисс между подтипом, удобством и безопасностью типов.Решение на данный момент: будьте более осторожны при рефакторинге.

3 голосов
/ 18 января 2012

Посмотрите на этот ответ М. Одерского.

Резюме

Проверки совпадений незапечатанных иерархий выполнимы, нетривиальны и нет (пока нет)) реализовано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...