Sam Bean
Sam Bean

Reputation: 39

Error Calling Generic Function In Scala

So I'm following fpinscala and I have this Object:

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
        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: _*))

    def tail[A](as: List[A]): List[A] = as match {
        case Nil => as
        case Cons(_, xs) => xs 
    }

    def setHead[A](as: List[A], a: A): List[A] = as match {
        case Nil => Cons(a, Nil)
        case Cons(_, xs) => Cons(a, xs)
    }

    def main(args: Array[String]): Unit = 
        println(tail(List(1,2,3)))
}

When I try to run main I get:

 error: type mismatch;
 found   : List[Int] (in scala.collection.immutable)
 required: List[?]   (in <empty>)
        println(tail(List[Int](1,2,3)))

I have followed the book pretty exactly so I don't know what I'm missing here. It says you should now be able to call List(1, 2, 3, 4) or List("hello", "goodbye") with no issues. But I can't pass that to the function? Some insight on what I'm missing would be appreciated.

Upvotes: 0

Views: 94

Answers (1)

Mikel San Vicente
Mikel San Vicente

Reputation: 3863

The code compiles correctly, the only problem I see is that you are declaring the main method in the List companion object and that is incorrect, you should move it to other object:

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
        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: _*))

    def tail[A](as: List[A]): List[A] = as match {
        case Nil => as
        case Cons(_, xs) => xs 
    }

    def setHead[A](as: List[A], a: A): List[A] = as match {
        case Nil => Cons(a, Nil)
        case Cons(_, xs) => Cons(a, xs)
    }
}
object Main {
    def main(args: Array[String]): Unit = 
        println(List.tail(List(1,2,3)))
}

Upvotes: 3

Related Questions