Chapter 4.  Basic Pattern Matching

This chapter continues the study of functional programming foundations that the previous chapter opened. It covers basic data pattern matching. Pattern matching is an essential feature-rich mechanism of powerful data processing that is embedded into the F# language's core.

A good grasp of the F# pattern matching features is an absolute must for an enterprise developer because most of the time, enterprise business is revolving around sophisticated data transformations in Line Of Business (LOB) applications (https://blogs.msdn.microsoft.com/dragoman/2007/07/19/what-is-a-lob-application/) and along Extract Transform Load (ETL) (https://en.wikipedia.org/wiki/Extract,_transform,_load) cycles in data warehousing and business analytics.

I intentionally narrowed down the subject of this chapter to basic pattern matching for a merely didactic reason. Usually, F# beginners first grasp pattern matching as an imperative switch on steroids or just a semantically equivalent way of coding lengthy if...then...elif...elif... ...else... expressions. Then, they begin to recognize the role of pattern matching in data structures decomposition. And finally, the pattern matching knowledge acquisition gets completed with embracing active patterns.

The goal of this chapter is to provide you with a thorough grasp of the pattern matching features associated with the F# match construction:

  • The overall composition of this rather complicated language construction
  • Tacit assumptions behind the parts of match (the ordering of matching rules and completeness of pattern cases, to name a few)
  • Specific kinds of pattern cases and how to build composite cases

The decomposition abilities consideration is postponed until the coverage of the data structures in the upcoming chapters. Similarly, I will cope with active patterns when covering the advanced programming techniques of F#.

An explicit form of pattern matching with match construction

Explicit match construction in F# belongs to control flow elements, along with if-then-else, or while-do. Of other F# bits and pieces, a match is a relatively complicated combination of the following parts and governing rules:

match comparison-expression with 
  | pattern-expression1 -> result-expression1 
  ......................................... 
  | pattern-expressionN -> result-expressionN 

It works in this manner, that is, comparison-expression is juxtaposed with each pattern-expression beginning with pattern-expression1 and goes down the list until either the first match occurs, or passing pattern-expressionN still non-matched. If a match is found for pattern-expressionX, then the result of the entire construction is the result of result-expressionX. If no matches are found, then MatchFailureException is thrown, indicating that the match cases were incomplete.

The key points of pattern matching that are often missing by F# beginners on the first read are as follows:

  • The match construction represents an expression, like any other F# construction excluding value binding. This means that the value of one and only one of result-expressions will be taken for the value of the entire construction (given that a certain matching has indeed taken place).
  • Every pattern-expression1 through pattern-expressionN must share the same type, which is also the same with the type of comparison-expression in order for the match construction to compile.
  • Every result-expression1 through result-expressionN must share the same type in order for the match construction to compile.
  • Listed pattern to result cases are tried at run-time one after another in the top-down order. This arrangement prescribes a certain ordering of the cases from the standpoint of pattern commonality. More specific patterns must precede less specific ones; otherwise, more specific patterns will not have chances to be matched ever.
  • The set of alternatives represented by all patterns must be exhaustive; otherwise, matching comparison-expression not covered by any of the patterns will cause MatchFailureException.
  • More atomic pattern terms can be composed into broader pattern expressions using Boolean logic operators OR (|), AND (&), and a special when guard.

Now, I will walk you through the multiplicity of pattern kinds so that you get used to their broad repertoire and become comfortable with getting around match expressions.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset