Pattern matching is a vital aspect of functional programming. It can make our code more expressive by eliminating noise. We’ll look into a few more patterns that give us the power and flexibility to create readable match expressions.

## OR Pattern

The **OR** pattern is used to group multiple patterns which return the same result. This can be considered a short hand for multiple patterns. A simple match expression verifying a number is below 10 and prime can be written multiple ways.

```
// Return value for each number
let isPrimeBelow10 = match number with
| 2 -> true
| 3 -> true
| 5 -> true
| 7 -> true
| _ -> false
// Using the OR pattern
let isPrimeBelow10 = match number with
| 2 | 3 | 5 | 7 -> true
| _ -> false
```

The second version of `isPrimeBelow10`

is easier to reason about as it declares the patterns 2, 3, 5, and 7 are grouped to the same result. The noise of all the extra `-> true`

has been removed. This gives the reader a visual cue about the relationships of the patterns as well as reduces duplicate code.

## Guards

Guards are used to match on patterns that require more than a constant. We use the **when** keyword followed by an expression which evaluates to a boolean. If the guard expression evaluates to `true`

then that pattern matches. Let’s say we want to classify a value as normal if it is within 100 to 200. That would take a lot of patterns if we used the **OR** pattern exclusively. It also doesn’t solve the situation if we wanted to indicate whether the value was high or low. We can use guards to accomplish our task.

```
let withinNormals number = match number with
| x when x > 200 -> High
| x when x < 100 -> Low
| _ -> Normal
```

We have three patterns with two of them using guards. The first pattern binds `number`

to the label `x`

and evaluates `x > 200`

. If it evaluates to true, the match returns `High`

. The second pattern does something similar, with the exception of evaluating `x < 100`

. The final pattern is a wildcard which returns if the previous patterns are not matched.

Guards allow us to do more than just match on constants. We can expand our `withinNormals`

to be more reusable.

```
let withinNormals (lowLimit, highLimit) number =
match number with
| x when x > highLimit -> High
| x when x < lowLimit -> Low
| _ -> Normal
```

We have the same three patterns but this time we are using the arguments passed in determine the lower and upper limit. Guards let us do more than match on constant values, they give us the flexibility to create reusable patterns.

## Deconstruct

Deconstruction allow the pattern to focus on what is being pattern matched. We left off Pattern Matching with Constants with a pattern matched version of Fizz Buzz. Here is the implementation again.

```
let printFizzBuzz number = match (number % 3, number % 5) with
| (0, 0) -> printfn "FizzBuzz"
| (0, _) -> printfn "Fizz"
| (_, 0) -> printfn "Buzz"
| _ -> printfn "%d" number
```

The `printFizzBuzz`

function takes a number and creates a tuple of the results of `number`

modulus 3 and 5. Our patterns deconstruct the tuple and match those results with constants.

We can even completely ignore values from deconstructed objects. Here we only care about the third value in the tuple. We are using the patterns to deconstruct the tuple while ignoring the first two values in the tuple. Our patterns are only focused on the values important to it.

```
match tupleOf3 with
| (_,_,0) -> "0"
| (_,_,1) -> "1"
| (_,_,x) when x < 0 -> "Negative"
| _ -> "Larger than 1"
```

## Summary

The OR pattern can be used to group patterns together which have the same return value. Redundant code can be eliminated with the use of the OR pattern. Guards give match expressions the ability to compare values in patterns and not restrict us to constants. Deconstruction let patterns focus on what is being matched instead of dealing with the whole object.