Reputation: 53826
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
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