Search code examples
scalalistcasematchingpruning

Scala Match Case structure and traversing a List with odd terms cs and m?


I am trying to understand this piece of code here

  def countChange(money: Int, coins: List[Int]): Int = (money, coins) match {
     case (0, _) => 1
     case (m, _) if m < 0 => 0
     case (_, cs)  if cs.isEmpty => 0
     case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail) 
  }
}

where I cannot understand the pairs (0,_), (m,_), (_,cs) and (m,cs) because the terms m and cs are undefined in the body of the code.

What is this construction in traversing the List called? A pair of some matching patterns?


Solution

  • The list is being traversed recursively. This construct is called pattern matching

    You can read it like:

    If the tuple (money, coins) is a tuple whose first value is 0 then return 1 ignore the second value of the tuple

    If the tuple (money, coins) is a tuple has a first value below 0 then return 0 ignore the second value of the tuple.

    And so on...

    The _ is used in pattern matching to simbolize that we don't care what that parameter is, it can be anything

    Pattern matching in Scala is backed by the unapply method of Objects, read more about extractors. Meaning that for each case the method unapply will be called with the tuple (money, coins) as argument and if determines that it is a match it will pass the respective first value and second value to the case clauses.

    Example:

    The statement case (m, _) => ... will lead to the call Tuple2.unapply((money, coins))

    Note

    Case classes already define unapply methods for us. That's why you can use them in pattern matching 'out of the box'. Tuple2 is a case class.