Home > Software engineering >  implementing List tail method in Scala
implementing List tail method in Scala

Time:01-02

I am teaching myself Scala. In particular, I am following the book Functional programming in Scala by Chiusano et al. Chapter 3 presents you with an implementation of a linked list:

sealed trait List[ A]
case object Nil extends List[Nothing]
case class Cons[ A](head: A, tail: List[A]) extends List[A]

object List{
  def sum(ints: List[Int]): Int = ints match{
  case Nil => 0
  case Cons(x, xs) => x   sum(xs)
  }

def product(ds: List[Double]): Double = ds match {
  case Nil => 1.0
  case Cons(0.0, _) => 0.0
  case Cons(x, xs) => x*product(xs)
  }      

def apply[A](as: A*): List[A] =
  if (as.isEmpty) Nil
  else Cons(as.head, apply(as.tail: _*))
}

and asks you to implement the function tail, that should return a list with all values but the first. I have implemented it in the following way:

def tail(ints: List[Int]): List[Int] = ints match {
  case Cons(x, xs) => xs
  }

(Partly, because I do not know how to implement the case in which the passed list is Nil). However, when I have tested it on List(1,2,3), the following is returned:

Cons(2,Cons(3,Nil))

instead of:

List(2, 3)  

which is what I was expecting. Besides, I am using intellij, and the IDE won't let me write List(1,2,3).tail, but only tail(List(1,2,3)).

Can anyone tell me what I am doing wrong? Why is my tail implementation giving me such a strange return value? Why won't the IDE let me write List(1,2,3).tail? How to implement the case in which the list passed is Nil?

CodePudding user response:

Why won't the IDE let me write List(1,2,3).tail?

What you've written is a stand-alone method that takes a List as a passed-in parameter. If what you want is to have a List return its own tail then you're actually half way there.

The Cons already has a tail member, you just have to promote it to the List definition and give the Nil a reasonable implementation.

sealed trait List[ A] {
  val tail: List[A]
}
case object Nil extends List[Nothing] {
  lazy val tail =
    throw new UnsupportedOperationException("tail of empty List")
}
case class Cons[ A](head: A, tail: List[A]) extends List[A]
  • Related