Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala pattern matching keep saying "match is not exhaustive!"

Tags:

match

scala

I want to leverage the warning that Scala issues when a matching is missing ("not exhaustive") - so that I don't forget one (I have dozens). The following simplified example shows my attempt:

sealed case class MESSAGE()
class SUCCESS_MESSAGE extends MESSAGE
class FAILURE_MESSAGE extends MESSAGE

def log(str: String, msgType: MESSAGE) {
    msgType match {
        case t:SUCCESS_MESSAGE => println("FAILURE: " + str)
        case t:FAILURE_MESSAGE => println("SUCCESS: " + str)
    }
}

The problem is that it says "match is not exhaustive!" although all possible combinations are listed. If I'd put the "case _ =>" in there, the whole point of the warning is invalidated for me because I could add

class INFO_MESSAGE extends MESSAGE

and no warning would be issued.

Is there a solution?

like image 350
stephanos Avatar asked Oct 25 '10 13:10

stephanos


2 Answers

Ideally, you shouldn't be extending a concrete class, and especially not a case class!

Given that there's no potential to customise SUCCESS_MESSAGE and FAILURE_MESSAGE, you probably also want to make these singletons.

Finally, underscores are a Bad Thing(tm) in Scala variable or class names. All UPPERCASE names are not idiomatic either. So:

sealed trait Message
case object SuccessMessage extends Message
case object FailureMessage extends Message

def log(str: String, msgType: Message) = msgType match {
  case SuccessMessage => println("Success: " + str)
  case FailureMessage => println("Failure: " + str)
}

Alternatively, and I would recommend this, you can wrap the actual message string:

sealed trait Message { def msg: String }
case class Success(msg:String) extends Message
case class Failure(msg:String) extends Message

def log(msg: Message) = msg match {
  case Success(str) => println("Success: " + str)
  case Failure(str) => println("Failure: " + str)
}
like image 127
Kevin Wright Avatar answered Oct 06 '22 02:10

Kevin Wright


You missed one case: The message might be an instance of MESSAGE, not one of its subclasses.

If you want to make this case impossible, you need to make MESSAGE abstract. This will make the warning go away.

like image 37
sepp2k Avatar answered Oct 06 '22 04:10

sepp2k