Match Error When Using View

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

compiles and returns true (albeit with a warning that the match is not exhaustive).

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

compiles (for now, we add type annotations for a and b ), but throw a 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) 

Why?

+6
source share
2 answers

Interestingly, the List.unapplySeq list List.unapplySeq not able to retrieve SeqViewLike objects, so you get a match error. But, on the other hand, Seq can. You can see it like this:

 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 

So, the fix for your second line would be:

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

So the problem is that List(1,2,3,4).view returns a SeqView .

Note that sliding already returns an Iterator , so List (1,2,3,4) .sliding (2) is lazy in that sense. Maybe view not needed.

+7
source

Well, a list view is not a list, it is a SeqView, which is a Seq. The right decision:

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

Source: https://habr.com/ru/post/899843/


All Articles