Pattern Matching

 Matching an Expression

 Introduction
 If you have an expression that can produce many outcomes but only one of them must be considered, you can validate it using the match keyword. The formula to follow is:
```match Expression with
| Condition 1 -> Result 1
| Condition 2 -> Result 2
| . . .```

The match and the with keywords are required. Expression can be the name of a variable whose value will be tested. The results of testing the Expression will be each validated in the next lines. Each line starts with | and a value from the Expression. This produces a result from the Condition X. That result is dealt with on the right side of ->. Here is an example:

```let a = 1;
let mutable gender = "N/A"

printfn "Before changing the value"
printfn "Gender: %s" gender

match a with
| 1 -> gender <- "Male"
| 2 -> gender <- "Female"
| y -> gender <- "Unknown"

printfn "After changing the value"
printfn "Gender: %s" gender```

This would produce:

```Gender: Male
Press any key to continue . . .```

Of course, you can perform the operation many times. Here is an example:

```let mutable house = 1;
let mutable property = "Unknown"

printfn "Before changing the value"
printfn "Type of Property: %s" property
printfn "--------------------------------------"

match house with
| 1 -> property <- "Condominium"
| 2 -> property <- "Townhouse"
| 3 -> property <- "Single Family"
| y -> property <- "Unknown"

printfn "After changing the value"
printfn "Type of Property: %s" property
printfn "--------------------------------------"

house <- 3

match house with
| 1 -> property <- "Condominium"
| 2 -> property <- "Townhouse"
| 3 -> property <- "Single Family"
| y -> property <- "Unknown"

printfn "After changing the value again"
printfn "Type of Property: %s" property
printfn "--------------------------------------"```

Here is an example:

```Before changing the value
Type of Property: Unknown
--------------------------------------
After changing the value
Type of Property: Condominium
--------------------------------------
After changing the value again
Type of Property: Single Family
--------------------------------------
Press any key to continue . . .```

Expression can be an expression as long as it produces a true or false value. Here are examples:

```let mutable employmentStatus = "Part-Time"
let mutable salary = 0.00
let mutable s =
match employmentStatus = "Full-Time" with
| true -> salary <- 32.48
| false -> salary <- 16.24

printfn "Employment Information";
printfn "Employment Status: %s" employmentStatus;
printfn "Hourly Salary:     %.2f" salary;
printfn "=---------------------------------=";

employmentStatus <- "Full-Time"
s <-
match employmentStatus = "Full-Time" with
| true -> salary <- 32.48
| false -> salary <- 16.24
printfn "Employment Information";
printfn "Employment Status: %s" employmentStatus;
printfn "Hourly Salary:     %.2f" salary;```

This would produce:

```Employment Information
Employment Status: Part-Time
Hourly Salary:     16.24
=---------------------------------=
Employment Information
Employment Status: Full-Time
Hourly Salary:     32.48
Press any key to continue . . .```

 Nesting Pattern Matching

You can create a pattern matching operation inside another. This is referred to as nesting. Here is an example:

```// -- Annual Compound Interest - Money Borrowed
let principal = 2500
let amountCategory =
if principal < 1000 then 1
elif principal < 2000 then 2
elif principal < 5000 then 3
else 4

let mutable periods = 0
let mutable typeOfPeriods = 3 //"Daily" // "Monthly" "Quarterly" "Annually"
let mutable compounded = "Quarterly"
let numberOfYears = 6
let mutable interestRate = 0.00

match typeOfPeriods with
| 1 ->
compounded <- "Daily"
periods <- 360
match amountCategory with
| 1 -> interestRate <- 2.25 / 100.00
| 2 -> interestRate <- 3.45 / 100.00
| 3 -> interestRate <- 4.35 / 100.00
| _ -> interestRate <- 6.05 / 100.00
| 2 ->
compounded <- "Monthly"
periods <- 12
match amountCategory with
| 1 -> interestRate <- 2.35 / 100.00
| 2 -> interestRate <- 2.95 / 100.00
| 3 -> interestRate <- 4.05 / 100.00
| _ -> interestRate <- 6.85 / 100.00
| 3 ->
compounded <- "Quarterly"
periods <- 4
match amountCategory with
| 1 -> interestRate <- 2.25 / 100.00
| 2 -> interestRate <- 4.30 / 100.00
| 3 -> interestRate <- 5.55 / 100.00
| _ -> interestRate <- 7.35 / 100.00
| 4 ->
compounded <- "Annually"
periods <- 1
match amountCategory with
| 1 -> interestRate <- 3.15 / 100.00
| 2 -> interestRate <- 4.35 / 100.00
| 3 -> interestRate <- 6.25 / 100.00
| _ -> interestRate <- 8.05 / 100.00
| _ -> periods <- 0
interestRate <- 0.00

// Calculation
let compoundInYears = float periods * float numberOfYears
let n1 = float 1 + (interestRate / float periods)
let futureValue = float principal * (n1 ** compoundInYears)

printfn "Deposit Summary"
printfn "--------------------------"
printfn "Amount Deposited: %d" principal
printfn "Interest Rate:    %0.02f%c" (interestRate * 100.00) '%'
printfn "Periods:          %i years" periods
printfn "Compounded:       %s" compounded
printfn "--------------------------"
printfn "Future Value:    %0.02f" futureValue
printfn "=========================="```

This would produce:

```Deposit Summary
--------------------------
Amount Deposited: 2500
Interest Rate:    5.55%
Periods:          4 years
Compounded:       Quarterly
--------------------------
Future Value:    3479.89
==========================
Press any key to continue . . .```
 Logical Operators

Instead of one value, you can use a combination of value in pattern matching. The values can be of the same type. Here is an example:

```let original  = false // true
let diagnosis = "Positive" // "Negative"

match original, diagnosis with
| true, "Positive" -> printfn "The sick patient was correctly diagnosed as sick"
| false, "Positive" -> printfn "The healthy patient was incorrectly diagnosed as sick"
| true, "Negative" -> printfn "The healthy patient was correctly diagnosed as healthy"
| false, "Negative" -> printfn "The sick patient was incorrectly diagnosed as healthy"
| _ -> ()```

This would produce:

```The healthy patient was incorrectly diagnosed as sick
Press any key to continue . . .```

The values can also be of different types. Here is an example:

```let principal = 12500.00
let compounded = "Yearly"
let periods = 5.00 // years
let mutable interestRate = 0.00

let mutable importance = 0

if principal < 2000.00 then importance <- 1
elif principal < 5000.00 then importance <- 2
elif principal < 10000.00 then importance <- 3
elif principal >= 10000.00 then importance <- 4

match importance, compounded with
| 1, "Daily" -> interestRate <- 3.95 / 100.00
| 1, "Monthly" -> interestRate <- 2.55 / 100.00
| 1, "Yearly" -> interestRate <- 1.95 / 100.00
| 2, "Daily" -> interestRate <- 5.45 / 100.00
| 2, "Monthly" -> interestRate <- 3.85 / 100.00
| 2, "Yearly" -> interestRate <- 3.35 / 100.00
| 3, "Daily" -> interestRate <- 7.45 / 100.00
| 3, "Monthly" -> interestRate <- 6.65 / 100.00
| 3, "Yearly" -> interestRate <- 4.85 / 100.00
| 4, "Daily" -> interestRate <- 9.75 / 100.00
| 4, "Monthly" -> interestRate <- 7.95 / 100.00
| 4, "Yearly" -> interestRate <- 5.85 / 100.00
| _ -> interestRate <- 1.25 / 100.00

let futureValue = principal + (principal * interestRate * periods)

printfn "Investment"
printfn "--------------------------"
printfn "Principal:      %0.0f" principal
printfn "Interest Rate:  %0.02f%c" (interestRate * 100.00) '%'
printfn "Periods:        %0.0f years" periods
printfn "--------------------------"
printfn "Interest Amount: %0.02f" (principal * interestRate * periods)
printfn "Future Value:    %0.02f" futureValue
printfn "=========================="```

This would produce:

```Investment
--------------------------
Principal:      12500
Interest Rate:  5.85%
Periods:        5 years
--------------------------
Interest Amount: 3656.25
Future Value:    16156.25
==========================
Press any key to continue . . .```