Ошибка при использовании вида - PullRequest
6 голосов
/ 22 октября 2011
List(1,2,3,4).sliding(2).map({ case List(a, b) => a < b }).forall(identity)

компилирует и возвращает true (хотя и с предупреждением о том, что совпадение не является исчерпывающим).

List(1,2,3,4).view
   .sliding(2).map({ case List(a: Int, b: Int) => a < b }).forall(identity)

компилируется (при условии, что мы включаем аннотации типов для a и b), но выдает MatchError:

scala.MatchError: SeqViewC(...) (of class scala.collection.SeqViewLike$$anon$1)
        at $anonfun$1.apply(<console>:12)
        at $anonfun$1.apply(<console>:12)
        at scala.collection.Iterator$$anon$19.next(Iterator.scala:335)
        at scala.collection.Iterator$class.forall(Iterator.scala:663)
        at scala.collection.Iterator$$anon$19.forall(Iterator.scala:333)

Почему?

Ответы [ 2 ]

7 голосов
/ 22 октября 2011

Интересно, что экстрактор списка List.unapplySeq не может извлечь SeqViewLike объектов, поэтому вы получаете ошибку соответствия. Но с другой стороны Seq может. Вы можете видеть это так:

scala> val seqView = List(1,2).view.sliding(2).next
seqView: scala.collection.SeqView[Int,List[Int]] = SeqViewC(...)

scala> val List(a, b, _*) = seqView

scala.MatchError: SeqViewC(...) 

scala> val Seq(a, b, _*) = seqView
a: Int = 1
b: Int = 2

Таким образом, исправление вашей второй строки будет:

List(1,2,3,4).view.sliding(2).map({ case Seq(a, b) => a < b }).forall(identity)
// res: Boolean = true

Итак, проблема в том, что List(1,2,3,4).view возвращает SeqView.

Обратите внимание, что sliding уже возвращает Iterator, поэтому List (1,2,3,4) .sliding (2) ленив в этом смысле. Может быть view не обязательно.

6 голосов
/ 22 октября 2011

Ну, представление списка - это не список, это SeqView, который является Seq.Следующее делает правильно:

List(1,2,3,4).view
   .sliding(2).map({ case Seq(a: Int, b: Int) => a < b }).forall(identity)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...