Reputation: 198218
To use ::
to pattern match a list:
val ::(a, tail) = List(1,2,3)
// a: Int = 1
// tail: List[Int] = List(2, 3)
But with List
:
val List(a, tail) = List(1,2,3)
// match error
I tried to figure out why the later one can't be matched, but without lucky.
I see in the abstract class SeqFactory
, there is a unapplySeq
method:
def unapplySeq[A](x: CC[A]): Some[CC[A]] = Some(x)
But when x
is List[Int]
, the return value is still Some[List[Int]]
, I can't find where the magic is
Upvotes: 3
Views: 81
Reputation: 12104
The reason for this is quite simple.
List(1,2,3)
is a list containing 3 elements: [1,2,3]
, similarly List(head, tail)
is a list containing 2 elements: [head, tail]
. It is not however a head and its tail.
scala> val hd :: tl = List(1,2,3) // val hd :: tl works the same as ::(hd, tl)
hd: Int = 1
tl: List[Int] = List(2,3)
scala> val List(a,b,c) = List(1,2,3)
a: Int = 1
b: Int = 2
c: Int = 3
So when you want to unapply a list using List
you need to match the exact number of items in said list. Otherwise use the more historical ::
operator to get the head and the tail
Upvotes: 3