Question about: match may not be exclusive


#1

The scala compiler warns that a particular match may not be exclusive. But I believe it is. It tells me the object List() is a failure example. First question is: What is List() ?

Second question, can someone help me understand why the match is not exclusive and how I should fix it?
The reason I think it is indeed an exclusive match is because the first element of the list may only be (,In) or (,Out). Perhaps I’ve defined the enumerated type incorrectly?
I copied the Enumeration example from https://www.scala-lang.org/api/current/scala/Enumeration.html

The offending line is marked with ///// HERE <—
Thanks anyone for the help.

object mainapp {

  def TestExclusive(a:Array[Int]):Int = {
    object Direction extends Enumeration {
      type Direction = Value
      val In, Out = Value
    }
    import Direction._
    type Event = (BigInt,Direction)

    def cmpPair(p1:Event,p2:Event):Boolean = (p1,p2) match {
      case ((r1, c1), (r2, c2)) =>
        if (r1 == r2)
          (c1, c2) match {
            case (In,Out) => true
            case _ => false
          }
        else
          r1 < r2
    }
    def encodeEvents(pair:(Int,Int)):List[Event]= {
      pair match {
        case (radius,center)=>List((BigInt(center)-radius,In),(BigInt(center)+radius,Out))
      }
    }
    val events:List[Event] = a.zipWithIndex.flatMap(encodeEvents).sortWith(cmpPair).toList
    val maxIntersections = 10000000 // if number of intersections exceeds this, return -1

    def handleEvents(events:List[Event],active:Int,intersecting:BigInt):Int = {
      if (intersecting > maxIntersections)
        -1
      else
        events match { ///// HERE <--- THIS IS THE MATCH TRIGGERING THE COMPILER WARNING
          case (_, In) :: tail => handleEvents(tail, active + 1, intersecting + BigInt(active))
          case (_, Out) :: tail => handleEvents(tail, active - 1, intersecting)
          case Nil => intersecting.toInt
        }
    }
    handleEvents(events,0,0)
  }
}

#3

(Note: I think your question is having problems displaying, probably because of embedded underscores. Underscore is significant in Markdown, so you need to escape it.)

Not my area of expertise, but I suspect the problem may be the definition of Direction. Scala’s current Enumeration type isn’t much-loved, for a variety of reasons – IIRC, one of those reasons is that it doesn’t participate in exhaustiveness checking. So you might want to redefine Direction as a sealed trait instead; that might provide enough clue to the compiler.


#4

Yep, pattern matching exhaustivity analysis does not know about Enumeration, sadly: https://github.com/scala/bug/issues/4333

Ironically, it does know about sealedness of Java enums :slight_smile: Sealed classes are checked for exhaustivity. (In Scala 3 there will be language support for enums/ADTs.)


#5

And it shouldn’t know about it either, not only because that’s special casing some privileged data type, but also the sadness related to https://github.com/scala/bug/issues/10747


#6

If they swipe left, the match may not be exclusive.