Pierrew
Pierrew

Reputation: 482

Scala pattern-matching confusion

I start learning Scala and I don't quite understand some behaviors of pattern-matching. Can anyone explain to me why the first case works but the second case doesn't work?

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)

Upvotes: 3

Views: 202

Answers (3)

Justin Pihony
Justin Pihony

Reputation: 67115

The reason is that there is no unapply method on an object of type ++. The reason that :: works is because behind the scenes it is really:

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
}

Source

This leads to how pattern matching is implemented in Scala. It uses extractors (or here), which are basically objects that contain an unapply method, which is provided by default with case classes.

Upvotes: 6

Brian
Brian

Reputation: 20295

In case two, ++ isn't used for unapply. You want the extractor :: to decompose the list.

A good 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

Upvotes: 1

Dan Osipov
Dan Osipov

Reputation: 1431

++ is a method on object of list. I think you want:

def getSumofFirstTwoElement(list: List[Int]): Int = list match {
     case a::b::tail => a + b
     case _ => -1
}

Upvotes: 1

Related Questions