Using comparison operators in Scala's pattern matching system

后端 未结 4 555
忘掉有多难
忘掉有多难 2020-12-07 11:02

Is it possible to match on a comparison using the pattern matching system in Scala? For example:

a match {
    case 10 => println(\"ten\")
    case _ >         


        
相关标签:
4条回答
  • 2020-12-07 11:26

    You can add a guard, i.e. an if and a boolean expression after the pattern:

    a match {
        case 10 => println("ten")
        case x if x > 10 => println("greater than ten")
        case _ => println("less than ten")
    }
    

    Edit: Note that this is more than superficially different to putting an if after the =>, because a pattern won't match if the guard is not true.

    0 讨论(0)
  • 2020-12-07 11:30

    A solution that in my opinion is much more readable than adding guards:

    (n compare 10).signum match {
        case -1 => "less than ten"
        case  0 => "ten"
        case  1 => "greater than ten"
    }
    

    Notes:

    • Ordered.compare returns a negative integer if this is less than that, positive if greater, and 0 if equal.
    • Int.signum compresses the output from compare to -1 for a negative number (less than 10), 1 for positive (greater than 10), or 0 for zero (equal to 10).
    0 讨论(0)
  • 2020-12-07 11:39

    As a non-answer to the question's spirit, which asked how to incorporate predicates into a match clause, in this case the predicate can be factored out before the match:

    def assess(n: Int) {
      println(
        n compare 10 match {
          case 0 => "ten"
          case 1 => "greater than ten"
          case -1 => "less than ten"
        })
    }
    

    Now, the documentation for scala.math.Ordering.compare(T, T) promises only that the non-equal outcomes will be greater than or less than zero. Java's Comparable#compareTo(T) is specified similarly to Scala's. It happens to be conventional to use 1 and -1 for the positive and negative values, respectively, as Scala's current implementation does, but one can't make such an assumption without some risk of the implementation changing out from underneath.

    0 讨论(0)
  • 2020-12-07 11:45

    While all the above and bellow answers perfectly answer the original question, some additional information can be found in the documentation https://docs.scala-lang.org/tour/pattern-matching.html , they didn't fit in my case but because this stackoverflow answer is the first suggestion in Google I would like to post my answer which is a corner case of the question above.
    My question is:

    • How to use a guard in match expression with an argument of a function?

    Which can be paraphrased:

    • How to use an if statement in match expression with an argument of a function?

    The answer is the code example below:

        def drop[A](l: List[A], n: Int): List[A] = l match {
          case Nil => sys.error("drop on empty list")
          case xs if n <= 0 => xs
          case _ :: xs => drop(xs, n-1)
        }
    

    link to scala fiddle : https://scalafiddle.io/sf/G37THif/2 as you can see the case xs if n <= 0 => xs statement is able to use n(argument of a function) with the guard(if) statement.

    I hope this helps someone like me.

    0 讨论(0)
提交回复
热议问题