Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to suppress "match is not exhaustive!" warning in Scala

How can I suppress the "match is not exhaustive!" warning in the following Scala code?

val l = "1" :: "2" :: Nil
l.sliding(2).foreach{case List(a,b) => }

The only solution that I found so far is to surround the pattern matching with an additional match statement:

l.sliding(2).foreach{x => (x: @unchecked) match {case List(a,b) => }}

However this makes the code unnecessarily complex and pretty unreadable. So there must be a shorter and more readable alternative. Does someone know one?

Edit

I forgot to mention that my list l has at least 2 elements in my program. That's why I can safely suppress the warning.

like image 699
Stefan Endrullis Avatar asked Nov 05 '12 10:11

Stefan Endrullis


3 Answers

Here are several options:

  1. You can match against Seq instead of List, since Seq doesn't have the exhaustiveness checking (this will fail, like your original, on one element lists):

    l.sliding(2).foreach{case Seq(a, b) => ... }
    
  2. You can use a for comprehension, which will silently discard anything that doesn't match (so it will do nothing on one element lists):

    for (List(a, b) <- l.sliding(2)) { ... }
    
  3. You can use collect, which will also silently discard anything that doesn't match (and where you'll get an iterator back, which you'll have to iterate through if you need to):

    l.sliding(2).collect{case List(a,b) => }.toList
    
like image 55
Steve Avatar answered Oct 18 '22 06:10

Steve


Making it complete with ; case _ => ??? is pretty short. ??? just throws an exception. You can define your own if you're using 2.9 or before (it's new in 2.10).

It really is pretty short compared to what you need for a match annotation:

(: @unchecked)
; case _ => ???
              ^  One more character!

It doesn't throw a MatchError, but does that really matter?

like image 20
Rex Kerr Avatar answered Oct 18 '22 05:10

Rex Kerr


Since your sliding(2) can possibly return one last list with only one element in it, you should also test it:

l sliding(2) foreach {
  case a::b::Nil => println("two elements: " + a + b)
  case l         => println("one last element" + l.head)
}
like image 3
Lomig Mégard Avatar answered Oct 18 '22 05:10

Lomig Mégard