At this point, I believe you would agree that pattern matching is a powerful data transformation feature. Just to further amplify the facilities considered so far, F# offers enhancing pattern-expressions
with additional matching logic. Guard is represented by an arbitrary boolean expression that is attached to pattern-expression
using the when
keyword. The guard kicks in only if its pattern-expression
host has matched. Then, the guard expression is computed, and if true
, it springs the transformation performed by the corresponding result-expression
to the right. Otherwise, the entire rule is considered non matched, and the matching continues in an usual manner. The when
guards can be mixed and matched within a match
construction in a completely arbitrary manner.
To demonstrate when
guards in action, let me slightly modify the previous example. In the case where both keys are not empty, there are two subcases: when the keys are equal to each other and when they are not. Furthermore, our function would be required to format the result for each of these cases differently.
All that is required for this modification is just one extra line of code preceding the last one (remember that I want to add a more specific match case, and then it must go in front of a more generic one). The code is as follows:
| (x,y) when x = y -> sprintf "both keys are not empty: keyA = keyB = %s" x
That's it for this modification. I encourage you to play with both scripts Ch4_4.fsx
and Ch4_5.fsx
in FSI by entering different arguments provided in the scripts and observing the changing function behavior.