blue-sky
blue-sky

Reputation: 53826

What is A* for method parameter?

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

Upvotes: 0

Views: 190

Answers (1)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297205

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]

Upvotes: 4

Related Questions