angus angus - 2 months ago 19
Scala Question

FP Pattern matching

I just started to learn FP with Scala so apologize for the question. I found this exercise (Exercise 3.1 https://www.scala-exercises.org/fp_in_scala/functional_data_structures) for pattern matching but I am a bit confuse and having trouble to understand how come the result for X is 3.

val x = List(1, 2, 3, 4, 5) match {
case Cons(x, Cons(2, Cons(4, _))) => x
case Nil => 42
case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y
case Cons(h, t) => h + sum(t)
case _ => 101
}


Can some please assist here with debugging this scenario step by step ? I believe that this will help me to understand the concept.

Thanks.

Answer

An immutable List in Scala is a Cons-list. That means that it consists of a series of Cons-objects, and is ending with a Nil. For example, your list:

List(1, 2, 3, 4, 5)

would be this Cons-list:

Cons(1, Cons(2, Cons(3, Cons(4, Cons(5, Nil)))))

When you pattern-match on lists in Scala, you can use this Cons-structure. And that is what that example does.

Let me go through each of the patterns to tell you what they do:

  1. This one matches if your second element is a 2 and your third element is a 4. If that is the case, the expression returns the first element of the list. The _ means that you ignore the rest of the list (so it could be 3 elements or more).

    case Cons(x, Cons(2, Cons(4, _))) => x
    
  2. This one matches the empty list. If it matches, the expression returns 42.

    case Nil => 42
    
  3. This one matches if your third element is 3 and your fourth element is 4. If it matches, the expression returns the sum of the two first elements of the list.

    case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y
    
  4. This one matches all lists with at least one element. If it matches, the expression returns the first element plus the sum of the rest of the list (which basically equals the sum of the entire list).

    case Cons(h, t) => h + sum(t)
    
  5. This one matches everything else. It is the default case, and returns 101. This should never happen, as all other cases are covered above it.

    case _ => 101
    

As you hopefully can see now, the value of x becomes 3 because it matches with the third case. This returns 1 + 2, which equals 3.