I have recently started reading the book Functional Programming in Scala by Paul Chiusano and Rúnar Bjarnason, as a means to learn FP. I want to learn it because it will open my head a bit, twist my way of thinking and also hopefully make me a better programmer overall, or so I hope.
In their book, Chp. 3, they define a basic singly-linked-list type as follows:
package fpinscala.datastructures
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: _*))
}
I'm now working on implementing the tail method, which shall work similarly to the tail method defined in Scala libraries. I guess that the idea here, is to define a tail method inside the List object, what they call a companion method, and then call it normally in another file (like a Main file).
So far, I have this:
def tail[A](ls: List[A]): List[A] = ls match {
case Nil => Nil
case Cons(x,xs) => xs
}
Then I created a Main file in another folder:
package fpinscala.datastructures
object Main {
def main(args:Array[String]):Unit = {
println("Hello, Scala !! ")
val example = Cons(1, Cons(2, Cons(3, Nil)))
val example2 = List(1,2,3)
val example3 = Nil
val total = List.tail(example)
val total2 = List.tail(example3)
println(total2)
}
}
This works and gives me:
Hello, Scala !!
Cons(2,Cons(3,Nil))
My question is:
Is this the correct way to write the tail method, possibly, as the authors intended? And is this package structure correct? Because it feels very wrong to me, although I just followed the authors package.
I also don't know if I should have used a specific type instead of writing a polymorphic method (is this the name?)...
Bear with me, for I am a newbie in the art of FP.