This is an excerpt from the 1st Edition of the Scala Cookbook (partially modified for the internet). This is Recipe 3.15, “How to use Lists in Scala match expressions.”
Problem
You know that a Scala List
data structure is a little different than other collection data structures. It’s built from “cons” cells and ends in a Nil
element. You want to use this to your advantage when working with a match
expression, such as when writing a recursive function.
Solution
You can create a List
like this:
val x = List(1, 2, 3)
or like this, using cons cells and a Nil
element:
val y = 1 :: 2 :: 3 :: Nil
When writing a recursive algorithm, you can take advantage of the fact that the last element in a List
is a Nil
object. For instance, in the following listToString
method, if the current element is not Nil
, the method is called recursively with the remainder of the List
, but if the current element is Nil
, the recursive calls are stopped and an empty String
is returned, at which point the recursive calls unwind:
def listToString(list: List[String]): String = list match { case s :: rest => s + " " + listToString(rest) case Nil => "" }
Running this example in the REPL yields the following result:
scala> val fruits = "Apples" :: "Bananas" :: "Oranges" :: Nil fruits: List[java.lang.String] = List(Apples, Bananas, Oranges) scala> listToString(fruits) res0: String = "Apples Bananas Oranges "
The same approach of (a) handling the Nil
condition and (b) handling the remainder of the List
can be used when dealing with a List
of other types:
def sum(list: List[Int]): Int = list match { case Nil => 0 case n :: rest => n + sum(rest) } def multiply(list: List[Int]): Int = list match { case Nil => 1 case n :: rest => n * multiply(rest) }
These methods are demonstrated in the REPL:
scala> val nums = List(1,2,3,4,5) nums: List[Int] = List(1, 2, 3, 4, 5) scala> sum(nums) res0: Int = 15 scala> multiply(nums) res1: Int = 120
Discussion
When using this recipe, be sure to handle the Nil
case, or you’ll get the following error in the REPL:
warning: match is not exhaustive!
In the real world (outside the REPL), you’ll get a MatchError
:
Exception in thread "main" scala.MatchError: List() (of class scala.collection.immutable.Nil$)
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |
See Also
- Recipe 3.11, “Using Pattern Matching in Match Expressions”, for more examples of using a
match
expression with multiple types