0

In below apply method what is "as: A*" ?

List(1, 2, 3) constucts a List of type : Cons(1,Cons(2,Cons(3,Nil)))

From reading the method code it appears that its a kind of syntax sugar for multiple type parameters of same type ?

  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 apply[A](as: A*): List[A] =
      if (as.isEmpty) Nil
      else {
        Cons(as.head, apply(as.tail: _*))
      }
  }

If this is true should'nt this be also valid :

object List {
    def apply[A](asHead: A , asTail : A): List[A] =
      if (asHead.isEmpty) Nil
      else {
        Cons(asHead.head, apply(asTail.tail: _*))
      }
blue-sky
  • 51,962
  • 152
  • 427
  • 752

1 Answers1

4

No, there's a difference here.

When you declare asHead: A, asTail: A, asHead and asTail have obviously the same type. However, in the original code that uses as: A*, the type of as.head is A, and the type of as.tail is Seq[A] -- as can be deduced from the types of head and tail. Therefore, your code is not the same thing.

The declaration A* stands for "a variable number of parameters of type A", usually known as vararg. This is similar to a Seq[A], but differ in the invocation:

apply(1, 2, 3) // A*
apply(Seq(1, 2, 3)) // Seq[A]

The counterpart to that is the : _* declaration when calling a vararg method with a sequence:

apply(Seq(1, 2, 3): _*) // A*
apply(Seq(1, 2, 3)) // Seq[A]
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681