Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exhaustiveness check for pattern matching in Scala 2.11

We have some pattern matching code where we would expect to be warned by the compiler that the match is not exhaustive, but we get none. Are there some cases where the exhaustiveness check can't be done?

E.g Our example (using scalactic Good+Bad):

(maybeModelIdOrFailure, maybeMake) match {

    case (Some(Good(modelId)), Some(makeId)) if modelId >= 0 && taxonomyService.isValidModel(makeId, modelId) =>
      Good(Some(MakeModelParameters(makeId, Some(modelId), modelLineId = None, index)))

    case (Some(Good(modelLineId)), Some(makeId)) if modelLineId < 0 && taxonomyService.isValidModelLine(makeId, -1 * modelLineId) =>
      Good(Some(MakeModelParameters(makeId, modelId = None, modelLineId = Some(-1 * modelLineId), index)))

    case (Some(Good(modelOrModelLineId)), Some(makeId)) =>
      Bad(One(IdNotFound(modelIdKeyName, modelOrModelLineId)))

    case (Some(Good(modelId)), None) if modelId >= 0 =>
      Bad(One(IdInvalid(modelIdKeyName, "Model Id without Make Id")))

    case (Some(Good(modelLineId)), None) if modelLineId < 0 =>
      Bad(One(IdInvalid(modelIdKeyName, "Model Line Id without Make Id")))

    case (None, Some(makeId)) => Good(Some(MakeModelParameters(makeId, None, None, index)))

    // case (None, None) => Good(None)

    // case (Some(Bad(invalidParams)), _) => Bad(One(invalidParams))
  }

We commented the last two lines, but the compiler doesn't warn and we didn't disable any checks.

like image 675
longliveenduro Avatar asked Dec 01 '15 13:12

longliveenduro


People also ask

Does Scala have pattern matching?

Scala's pattern matching statement is most useful for matching on algebraic types expressed via case classes. Scala also allows the definition of patterns independently of case classes, using unapply methods in extractor objects.

What is the use of Scala pattern matching?

Pattern matching is a way of checking the given sequence of tokens for the presence of the specific pattern. It is the most widely used feature in Scala. It is a technique for checking a value against a pattern. It is similar to the switch statement of Java and C.

How pattern matching works in a function's parameter list?

Pattern matching tests whether a given value (or sequence of values) has the shape defined by a pattern, and, if it does, binds the variables in the pattern to the corresponding components of the value (or sequence of values). The same variable name may not be bound more than once in a pattern.

What is pattern matching give an example?

For example, x* matches any number of x characters, [0-9]* matches any number of digits, and . * matches any number of anything. A regular expression pattern match succeeds if the pattern matches anywhere in the value being tested.


1 Answers

From Jason Zaugg's comment on SI-9232 it seems the guards currently simply disable exhaustiveness checks (or nearly so). If that's the reason, moving the guard conditions inside the branches (e.g. case (Some(Good(modelId)), None) => if (modelId >= 0) ... else ...) should help. Other related issues: https://issues.scala-lang.org/browse/SI-5365, https://issues.scala-lang.org/browse/SI-7631.

like image 124
Alexey Romanov Avatar answered Nov 08 '22 04:11

Alexey Romanov