Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match error while 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 (so long as we include the type annotations for a and b) but throws 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?

like image 914
Luigi Plinge Avatar asked Oct 22 '11 00:10

Luigi Plinge


2 Answers

That's interesting, the list extractor List.unapplySeq is not able to extract SeqViewLike objects, which is why you get a match error. But on the other hand Seq can. You can see that 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 a fix to 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 issue 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 is that sense. May be view is not necessary.

like image 193
huynhjl Avatar answered Sep 19 '22 05:09

huynhjl


Well, a view of a list is not a list, it is a SeqView, which is a Seq. The following does the right thing:

List(1,2,3,4).view
   .sliding(2).map({ case Seq(a: Int, b: Int) => a < b }).forall(identity)
like image 28
Michael Lorton Avatar answered Sep 22 '22 05:09

Michael Lorton