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?
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With