1

For some reason the following code is unreachable. I cannot understand why my code will never get reached as this is a simple pattern matching. Here it is:

type Occurrences = List[(Char, Int)]

def combinations(occurrences: Occurrences): List[Occurrences] = occurrences match{
  case Nil => Nil
  case List() => List()
  case x => List(x)
  case x::xs => combinations(List((x._1,x._2 - 1))) ::: combinations(xs)
}

This algorithm is meant to extract all of the sub lists of the given list.

wingedsubmariner
  • 13,350
  • 1
  • 27
  • 52
Bula
  • 2,398
  • 5
  • 28
  • 54

4 Answers4

5

case x => List(x) matches anything. It looks like you want to match a 1-element list so you can use:

case l@List(_) => List(l)
Lee
  • 142,018
  • 20
  • 234
  • 287
3
scala> Nil == List()
res0: Boolean = true

What did you expect what List() is?

Btw, the error message does exactly tell you what the problem is:

scala> def combinations(occurrences: Occurrences): List[Occurrences] = occurrences match{
     |   case Nil => Nil
     |   case List() => List()
     |   case x => List(x)
     |   case x::xs => combinations(List((x._1,x._2 - 1))) ::: combinations(xs)
     | }
<console>:11: warning: patterns after a variable pattern cannot match (SLS 8.1.1)
         case x => List(x)
              ^
<console>:12: warning: unreachable code due to variable pattern 'x' on line 11
         case x::xs => combinations(List((x._1,x._2 - 1))) ::: combinations(xs)
                                                           ^
<console>:12: warning: unreachable code
         case x::xs => combinations(List((x._1,x._2 - 1))) ::: combinations(xs)
                                                           ^
combinations: (occurrences: Occurrences)List[Occurrences]
kiritsuku
  • 52,967
  • 18
  • 114
  • 136
1

I am a Scala newbie, and I ran into a similar problem, and was confused by the warning the compiler gave. Here's what confused me and what my solution was, if others run into the same thing.

My compiler gave me a warning roughly like this (but I'm substituting the OP's code in place of mine):

[warn] path/to/file.scala:123: unreachable code
case x::xs => combinations(List((x._1,x._2 - 1))) ::: combinations(xs)
                                                   ^

The compiler points to a symbol in your last case statement, where in fact (as others have mentioned) the problem lies in your List() case statement. I at first mistook this to mean there was a problem in the case statement the compiler prints. (In my case, a '::' that I thought I had used incorrectly.)

What the compiler message means is that the statement is unreachable, and has nothing to do with the character it points to. The reason the statement is unreachable, as others have mentioned, is that the List() statement is a catch-all, and the matching won't flow through to the rest of the cases.

To fix this, make sure the logic can flow through to all your cases and doesn't get stuck at a catch-all. i.e. go from most specific to least specific. I was also trying to match a list by the number of elements, and here's my solution [Compiles and works, with no warning!]:

def myFunction(myList: List[MyType]) = myList match {
   case x1 :: x2 :: xs => // match 2+ elems
   case x :: xs => // match 1+ elems
   case Nil => // match 0 elems

However, if I rearrange the first two lines, I get that unreachable code warning again, because the match 2+ case is more specific than the 1+ case [Doesn't work, and unreachable code warning!]:

def myFunction(myList: List[MyType]) = myList match {
   case x :: xs => // match 1+ elems
   case x1 :: x2 :: xs => // match 2+ elems
   case Nil => // match 0 elems
0

I guess you want to match one single element with case x => List(x). That matches anything.
Use case x :: Nil => List(x) instead.

Samy Dindane
  • 17,900
  • 3
  • 40
  • 50