
Pattern Matching:
Scala Pattern matching is one of the features of functional programming that make it such an awesome paradigm. This tool is somewhat similar to switch statements you might be familiar with from other languages such as Java or Python, however Scala pattern matching is a much more powerful tool. In short, pattern matching allows one to check a value against a pattern as well as partitioning a value into smaller components. We will see how pattern matching can be used to replace if-else statements, match type, simplify case classes, and provide an overall more efficient solution to certain tasks.
Replacing If-else Statements
Pattern matching is pretty intuitive to understand. Pick the value you would like to match, and define one or more case clauses that match the initial value. The ‘_’ can be used in Scala as a catch all for pattern matching, similar to an “else” in if-else statements. ‘|’ is used as an or to add multiple cases in a single case clause. Of course, since Scala is a functional programming language, the result of pattern matching returns a value. The examples below demonstrate how pattern matching can be used in place of an if-else statement.
Pattern Guards
If statements can be added to the case clauses to give more control over the specified patter, and allowing pattern matching to be a more powerful functionality.
Pattern Matching on Types
A powerful functionality of pattern matching is that it can be used to differentiate between types. Depending on the type of the variable, the program can perform a different action. This can be used in a wide variety of situations to create efficient, elegant code. Pattern matching follows the same format as before, but the case clause checks for a type rather than a value as seen below.
Pattern Matching on Case Classes
The idea of pattern matching on types can be expanded to provide a great functionality with case classes. Let’s say, for example, you have an abstract class with 10 sub-classes. Each of these sub-classes have 5 methods. The traditional approach would be to write these 5 methods in all 10 classes, for a total of 50 methods. With pattern matching, you can write these methods only once, with case clauses specifying the instructions based on which class-instance is calling the method. This vastly reduces the amount of code needed, and follows the fundamental DRY principle – “Don’t Repeat Yourself.” Below we can see how this idea works.
Instead of this…
We can do this…
Scala Options
Options are a type in Scala that offer a safer alternative to Null that you may be used to from other languages. Option will either hold 0 or 1 elements of a given type. In the case of 1 element being held, say of type T, option will hold Some[T]. If no element is being held, option will be equal to None.
Options and Maps
The get method for Scala maps returns an option. If the desired key is found, Some(value) is found that corresponds to the key. If the key is not found, None is returned. This functionality offers a much safer alternative to working with maps than the scary error-prone Null that is ever present in Java.
How to extract the Some value from a Scala Option
The some value can easily be extracted by either using pattern matching or using a method called getOrElse. The getOrElse method will return the Some value if it exists or will return an inputted string if Option is equal to None. Both methods are demonstrated below:
Scala Try
Try is an alternative error handling method to the try/catch you may know from other languages (it is also available in Scala). Try can be used when:
- An operation that may throw an exception
- You want to capture an exception rather than throw it
- “finally” is not needed
Try is very similar to Option, but instead of Some(T) and None, it returns Success(T) and Failure(exception). Try must be imported – import scala.util.{Try, Success, Failure}
Obtaining the success value can be done similarly to Option, by using pattern matching or getOrElse.
References:
https://docs.scala-lang.org/tour/pattern-matching.html
https://www.tutorialspoint.com/scala/scala_options.htm
https://www.scala-lang.org/api/2.13.3/scala/util/Try.html