Search code examples
scaladesign-patternspattern-matchingmatchingtail-recursion

What to set as default when the type is A (Scala)


I have an exercise in Scala in which I have to transform that kind of list (a,a,a,b,c,d,d,e,a,a) into ((a,3),(b,1),(c,1),(d,2),(e,1),(a,2)). I obviously know that my algorithm is not correct yet, but I wanted to start with anything. The problem is that I don't know how to turn on the function (last line), because the error is that whatever I take as previous' argument, it says that required: A, found: Int/String etc. The previous was meant to be as a head of the previous iteration.

def compress[A](l: List[A]): List[(A, Int)] = {
  def compressHelper(l: List[A], acc: List[(A, Int)], previous: A, counter: Int): List[(A, Int)] = {
    l match {
      case head::tail => {
        if (head == previous) {
          compressHelper(tail, acc :+ (head, counter+1), head, counter+1)
        }
        else {
          compressHelper(tail, acc :+ (head, counter), head, 1)
        }
      }
      case Nil => acc
    }
  }
  compressHelper(l, List(), , 1)
}

Solution

  • You don't need to pass previous explicitly, just look at the accumulator:

    def compress[A](l: List[A], acc: List[(A, Int)]=Nil): List[(A, Int)] =
       (l, acc) match {
           case (Nil, _) => acc.reverse
           case (head :: tail, (a, n) :: rest) if a == head =>
                compress(tail, (a, n+1) :: rest)
           case (head :: tail, _) => compress (tail, (head, 1) :: acc)
    }