0

I have the following piece of code (this is for my coursea assignment)

def balance(chars: List[Char]): Boolean = {
  def innerBalance(chars: List[Char], count: Int): Boolean = {
    if (chars.isEmpty) count == 0
    if (chars.head == '(') innerBalance(chars.tail, count+1)
    if (chars.head == ')') (count > 0) && innerBalance(chars.tail, count-1)
    innerBalance(chars.tail, count)
  }

  innerBalance(chars, 0)
} 

From what I can tell, it's very similar to the stew's answer on this Scala way to program bunch of if's but I don't know why the statement

if (chars.isEmpty) count == 0

always be false.

If I run a test like this

balance("".toList)

it just throws exception.

Thanks for your help. Regards,

Community
  • 1
  • 1
  • this is not a very idiomatic use of scala. I'd advice for use to use `match` to reduce verbosity and the complexity of your solution. – korefn Apr 08 '13 at 05:34

3 Answers3

4

In Scala you never should use return, but instead write expressions. The main issue with the code above is that you are not using if expressions, i.e. you have omitted the else part and therefore the compiler is inferring Unit (Java's void, which means that "nothing" gets returned).

As there are multiple alternatives in your case, I suggest you use a match expression:

chars match {
  case '(' :: Nil => ...
  case ')' :: Nil => ...
  case Nil        => count == 0
  case _          => innerBalance(chars.tail, count)
}
Heiko Seeberger
  • 3,702
  • 21
  • 20
2

Adding to Huw's answer, You can also use pattern matching to make it more elegant:

      def innerBalance(chars: List[Char], count: Int): Boolean = chars match {
          case _ if count < 0  => false
          case Nil             => count == 0
          case '(' :: rest     => innerBalance(rest, count + 1)
          case ')' :: rest     => innerBalance(rest, count - 1)
          case _ :: rest       => innerBalance(rest, count)
      }
Community
  • 1
  • 1
Marimuthu Madasamy
  • 13,126
  • 4
  • 30
  • 52
0

A block like

{
  if (a) b
  c
}

will do b if a is true, and then always do c. If you want c to happen only when a is false, you need to use else:

{
  if (a) b
  else c
}
Hugh
  • 8,872
  • 2
  • 37
  • 42
  • Thanks, that helps. I need to explicitly add "return" keyword for each of my statements. Just realized the my problem right after posting the question. – splazit Apr 08 '13 at 02:30