Yuva
Yuva

Reputation: 95

Nested pattern matching in Scala

I'm new to Scala and I'm trying to understand how pattern matching works. So I wrote this basic code, which returned the expected result:

def test(choice: Int): String = choice match {
  case x if x > 0 && x%2 == 0 => "positive even number"
  case x if x > 0 && x%2 != 0 => "positive odd number"
  case 0 => "null"
  case x if x < 0 && x%2 == 0 => "negative even number" 
  case x if x < 0 && x%2 != 0 => "negative odd number"
}

Now I'm trying to do something a little more elaborate:

def test(choice: Int): String = choice match {

  case x if x%2 == 0 => x match {
    case y if y > 0 => "even and positive number" 
    case y if y < 0 => "even and negative number"
    }
  case 0 => "null"
  case x if x%2 != 0 => x match {
    case y if y > 0 => "odd and positive number" 
    case y if y < 0 => "odd and negative number"
    }
}

But it failed. Here's the error message on the console:

scala> def test(choice: Int): String = choice match {
     |
     |   case x if x%2 == 0 => x match {
     | case y if y > 0 => "even and positive number"
     | Display all 600 possibilities? (y or n)
     [...]

     |  if y < 0 => "even and negative number"
<console>:5: error: '(' expected but identifier found.
 if y < 0 => "even and negative number"
    ^

    [...]

Can somebody tell me what I'm doing wrong and give me some details about what I misunderstand about Scala in general and the match method in particular.

Upvotes: 0

Views: 2022

Answers (2)

Jakub Kozłowski
Jakub Kozłowski

Reputation: 493

It compiles for me. The order of cases doesn't matter for the success of compilation (however, the case 0 branch will never match, because case x if x%2==0 matches x=0. You may want to make the case 0 branch the first one)

I believe your problem is because of using tabs instead of spaces in the terminal.

If you use this code in a file in a project, it'll compile just as well. If you want it to work in the console, you can either:

  • convert the tabs to spaces before pasting the code
  • enter paste mode in the REPL using the :paste command, paste the code and exit paste mode with Ctrl-D (or whatever the REPL tells you the combination is - that's the one on Mac).

Upvotes: 2

user unknown
user unknown

Reputation: 36259

In your first code, you test for x>0 in the first 2 cases, then for 0 itself.

In the second code, you don't test for x>0, but x%2 == 0 which already matches for x = 0, and a second, outer match isn't considered.

If you put the explicit 0 match on top, it might work, but I didn't look for a second error and only matched for the first error I could find. :)

Upvotes: 0

Related Questions