1
votes
package exer1

object excercise3 {
    println("Welcome to the Scala worksheet")   
    def max(xs: List[Int]): Int = {
        if (xs.isEmpty)
            println("No Values in List")
        else
            compare(xs.head, xs.tail)

        def compare(num: Int, tl: List[Int]): Int = {
            if (tl.isEmpty)
                num
            else if (num > tl.head)
                compare(num, tl.tail)
            else
                compare(tl.head, tl.tail)
        }
    }
}

I'm a new bee to Scala functional programming and during the course of learning, I wrote this program to get the max number among the list. But it is showing Type mismatch error. I'm not able to figure out what went wrong and where? Can anyone help me...!

1
It seems that there is a missing } before def compare() ...ProGM

1 Answers

2
votes

Scala implicitly returns the last statement in a block, which here is the if statement. In an if statement, both possible values (the then clause and the else clause) must have the same type for it to be typable.

In

if (xs.isEmpty)
    println("No Values in List")
else
    compare(xs.head, xs.tail)

the then returns Unit (println doesn't return anything), the else clause return an Int, and as you specified the return type of max, the compiler tells you found : Unit; required : Int.

You have multiple options here :

  • Use a specific return number when the list is empty (e.g-1), which is a terrible solution for many, many reasons (DON'T DO THIS)

  • Raise an IllegalArgumentException (a bit overkill, plus an empty list is not really an exception)

  • Return an Option[Int] (by far the best and 'most idiomatic' solution)

Edit : Btw, you can use pattern matching to make the code look a bit nicer :

def compare(i:Int,l:List[Int]):Int = l match {
  case Nil => i
  case a::tail if a > i => compare(a,tail)
  case _::tail => compare(i,tail)
}

def max(l:List[Int]) = l match {
  case Nil => None
  case a::tail => Some(compare(a,tail))
}