Scala pattern confusion
I am starting to learn Scala and I do not fully understand some of the pattern matching behaviors. Can someone explain to me why the first case works, but the second case doesn't?
1
def getFirstElement(list: List[Int]) : Int = list match {
case h::tail => h
case _ => -1
}
Scala> getFirstElement(List(1,2,3,4))
res: Int = 1
Scala> 1 :: List(1,2)
res: List[Int] = List(1, 1, 2)
2
def getSumofFirstTwoElement(list: List[Int]): Int = list match {
case List(a: Int, b: Int)++tail => a + b
case _ => -1
}
<console>:11: error: not found: value ++
Scala> List(1,2) ++ List(3,4,5)
res: List[Int] = List(1, 2, 3, 4, 5)
source to share
The reason is that there is no method unapply
for the type object ++
. The reason it works ::
is because behind the scenes it really is:
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
override def tail : List[B] = tl
override def isEmpty: Boolean = false
}
This leads to how pattern matching is implemented in Scala. It uses extractors (or here ), which are basically objects that contain a method unapply
that is provided by default by the case classes.
source to share
In case two, ++
it is not used for unapply. You want the extractor to ::
decompose the list.
Nice explanation here .
scala> def getSumofFirstTwoElement(list: List[Int]): Int = list match {
| case a::b::t => a + b
| case _ => -1
| }
getSumofFirstTwoElement: (list: List[Int])Int
scala> getSumofFirstTwoElement(List(1,2,3,4))
res0: Int = 3
source to share