Pattern matching
|
Pattern matching is a feature in functional programming languages such as Mathematica, Haskell and ML.
With certain data types implemented in these programming languages, such as a list, the construction of these types form a very definite structure. For example a list is defined as an element constructed on to an empty list, or an element constructed on a list. In Haskell syntax:
a:[] -- element constructed on an empty list a:[a,a] -- element constructed on a list
The structure is thus element:list
. When pattern matching, we assert that a certain piece of data is equal to a certain pattern. For example, in the function:
head (element:list) = element
we assert that the first element of head
's argument is called element, and the function returns this. We know that this is the first element because of the way lists are defined, a single element constructed onto a list. This single element must be the first.
In certain pattern matching, we may wish to disregard a certain part of the pattern, since we have no real use ascribing a name to it. In the example head
above, we have no use for list
, so we can disregard it, and thus write the function:
head (element:_) = element
If such data does not match a pattern, an error inevitably occurs, or another subfunction with a pattern that does match this data is called to handle this data. Often this is the case for the empty list, as an empty list does not have a head (the first element that is constructed).
Pattern matching failure can often be ascribed to a type signature that is not strong enough or is incorrect.
Pattern matching is not limited to mere lists, but to user-defined data types. In Haskell, the following code segment defines a data type Color
that associates an integer with a string.
data Color = ColorConstructor Integer String
The keyword ColorConstructor
is merely a tag to associate the different data types together. It is similar to a C struct
.
When we want to write functions to make Color
an abstract data type, we wish to write functions to interface with the data type, and thus we want to extract some data from the data type, for example, just the string or just the integer part of Color
.
If we pass a variable that is of type Color, how can we get the data out of this variable? Such programming languages aforementioned use pattern matching to do so. For example, for a function to get the integer part of Color
, we can write:
integerPart (ColorConstructor theInteger _) = theInteger
Or conversely:
stringPart (ColorConstructor _ theString) = theString