﻿ F# Collections: Tuples Tuples

 Fundamentals of Tuples

 Introduction
 A tuple is a series of values considered as one, as an entity. The tuple is not strictly a data type like an integer or a string, but a tuple is used as if it were. This means that you can declare a variable as a tuple but without specifying that there is such a data type.

A tuple is not a simple type like a primitive one (int, bool, float, etc). The reason is that, although a tuple is treated as such, it is internally made of distinguishable values. The values can be numbers, characters, strings, objects (from classes), etc. The members, also called elements, of a tuple can also consist of expressions, etc. The items, or members, or elements, of a tuple don't have to be of the same type.

 Creating a Tuple

To create a tuple, use the parentheses. Inside the parentheses, list the values separated by commas. Here are examples:

```// Integrals
( 1, 4, 6, 12, 36 )
// Characters
( 'b', 'd', 'e', 'g' )
// Strings
( "Aaron", "Jennifer", "Yerimah" )```

The items in the tuple can also come from previously declared and initialized variables. Here is an example:

```let nbr1 = 16
let nbr2 = 24
let nbr3 = 58

(nbr1, nbr2, nbr3);```

Now:

• If a tuple is made of one element, it is also called a singleton
• If a tuple is made of two elements, it is called a pair. Here is an example:
`("Frank", "James");`
• If a tuple is made of three elements, it is called a tripple
• If a tuple is made of four elements, it can be called a quadruple
• If a tuple is made of five elements, it can be called a quintuple
• If a tuple is made of six elements, it is called a sextuple
• If a tuple is made of seven elements, it is called a septuple
• If a tuple is made of eight elements, it is called an octuple
 The Types of Members of a Tuple

The tuple is the most fundamental collection in F#. As mentioned already, each element of a tuple can be a type different. Here is an example:

`(93849, "Anthony Franks", true, 28.85)`

In this case, we create a tuple of 5 elements (a quintuple). The first element holds a natural number as the employee number. The second element is a string that is the name of the employee. The third element holds a Boolean value, specifying whether the employee is full-time or not. The last element specifies the hourly salary of the employee.

 Naming a Tuple

If you plan to use a tuple many times, you should store it in a variable. When declaring the variable, use the let operator and assign the tuple to it. Here is an example:

`let numbers = ( 1, 4, 6, 12, 36 )`

As mentioned already, F# is an inferred language: the compiler is able to figure out the type of a value assigned to a variable or when the value is used. This also applies to tuples. When you create a tuple, once you specify its elements, the compiler applies the appropriate type to each member. Still, if you want, you can indicate the data type of each element. To do this, after the name of the tuple, type : followed by the type of each member; the types are separated by *. Here is an example:

`let numbers : int * int * int * int * int = ( 1, 4, 6, 12, 36 )`

If the elements are of different types, enter the appropriate type of an element in the corresponding placeholder. Here is an example:

`let studentInfo : int * string * char = ( 937404, "Bertha Herlin", 'F' )`
 Individual Variables From a Tuple

As you may have realized, a tuple is a list made of various items. As seen so far, you can create a tuple and store the whole list in one variable. An alternative is to declare various variables but indicate that each gets its value from a tuple. The variables, which means the values in the tuple, can be of different types but the number of variables and the number of elements in the tuple must be the same.

To declare various variables whose values would come from a tuple, separate their names with commas but initialize the group with a tuple. Here is an example:

```let a, b, c, d = (203814, "Frank", "Deuler", 'M')
```

After this declaration, each variable is initialized with the value corresponding to its position in the tuple.

 Binding Values to Elements of a Tuple

Binding a tuple consists of specifying the names of its elements by giving a name to each. The formula to follow is:

`let (Name1, Name2, Name_X) = (Valu1, Value2, Value_X)`

In this case, the first named element will have the first value of the tuple; the second named element will have the second value of the tuple, and so on. Here is an example:

`let (student1, student2, student3, student4, student5) = ("Frank", "James", "Aaron", "Jennifer", "Yerimah");`

Eventually, in your code, you will be able to refer to an element using its name. If you are not planning to refer to a certain element, you don't have to name it. In this case, you can replace its name with the underscore (_) wildcard or you can put _ in its placeholder. Here are examples:

`let (student1, _, student3, _, student5) = ("Frank", "James", "Aaron", "Jennifer", "Yerimah");`
 Using a Tuple

 Introduction

The primary way you can use a tuple consists of presenting its values to the user. To do this from the sprintf() function, use the %A placeholder. Here is an example:

```open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form(MaximizeBox = false,
Text = "Tuples",
ClientSize = new System.Drawing.Size(210, 64),
StartPosition = FormStartPosition.CenterScreen)

let lblNumbers : Label = new Label(AutoSize = true,
Text = "Numbers:",
Location = new Point(21, 24))

let result = sprintf "%A" ( 1, 4, 6, 12, 36 )

let txtNumbers : TextBox = new TextBox(Location = new Point(85, 21),
Text = result,
Size = new System.Drawing.Size(100, 20))

do Application.Run exercise   ```

This would produce: If the tuple is stored in a variable, you can convert the variable to a string before passing it to a Windows control. Here is an example:

```open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form(MaximizeBox = false,
Text = "Tuples",
ClientSize = new System.Drawing.Size(210, 64),
StartPosition = FormStartPosition.CenterScreen)

let lblNumbers : Label = new Label(AutoSize = true,
Text = "Numbers:",
Location = new Point(21, 24))

let numbers = ( 1, 4, 6, 12, 36 )

let txtNumbers : TextBox = new TextBox(Location = new Point(85, 21),
Text = string numbers,
Size = new System.Drawing.Size(100, 20))

do Application.Run exercise```
 Accessing the Elements of a Tuple

We saw earlier that you could declare various variables and initialize them using a tuple. You can then access the value of each variable, by its name, using the value in its corresponding position in the tuple. Here are examples:

```open System
open System.Drawing
open System.Windows.Forms

let exercise = new Form(Text = "Date Values",
MaximizeBox = false,
ClientSize = new System.Drawing.Size(218, 92),
StartPosition = FormStartPosition.CenterScreen)

let equation, solution = ("x-4=10", 14)

let lblEquation = new Label(AutoSize = true,
Text = "Equation:",
Location = new Point(23, 20))

let txtEquation = new TextBox(Text = equation,
Location = new Point(90, 17),
Size = new System.Drawing.Size(100, 20))

let lblSolution = new Label(AutoSize = true,
Text = "Solution:",
Location = new System.Drawing.Point(23, 55))

let txtSolution = new TextBox(Text = string solution,
Location = new Point(90, 52),
Size = new System.Drawing.Size(100, 20))

do Application.Run exercise```

This would produce: If you had bound the elements of a tuple, you can access each using its name. Here is an example: The quick ratio is a business equation that allows a company to find out whether it is currently ready to pay off all its current liabilities based on its current assets and inventory.
```open System
open System.Drawing
open System.Windows.Forms

let financialDecisionMaking = new System.Windows.Forms.Form(Text = "Date Values",
MaximizeBox = false,
ClientSize = new System.Drawing.Size(218, 110),
StartPosition = FormStartPosition.CenterScreen)

let (currentAssets, inventory, currentLiatilities) = (4841586.00, 682400.00, 2115351.00)

let lblCurrentAssets = new System.Windows.Forms.Label(AutoSize = true,
Text = "Current Assets:",
Location = new Point(23, 20))

let txtCurrentAssets = new System.Windows.Forms.TextBox(Text = string currentAssets,
Location = new Point(118, 17),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))

let lblInventory = new System.Windows.Forms.Label(AutoSize = true,
Text = "Inventory:",
Location = new System.Drawing.Point(23, 46))

let txtInventory = new System.Windows.Forms.TextBox(Text = string inventory,
Location = new Point(118, 44),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))

let lblCurrentLiabilities = new System.Windows.Forms.Label(AutoSize = true,
Text = "Current Liabilities:",
Location = new Point(23, 74))

let txtCurrentLiabilities = new System.Windows.Forms.TextBox(Text = string currentAssets,
Location = new Point(118, 71),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))

do System.Windows.Forms.Application.Run financialDecisionMaking```

This would produce: Remember that members that were not named cannot be accessed (by their names).

 Tuples and Functions

 Built-In Functions

To let you get the first value of a pair, the F# language provides a function named fst. This function takes a pair as argument. Here is an example:

`let first = fst (5, 73)`

To find the second member of a pair, you can call the snd() function. Here is an example:

`let second = snd (5, 73)`
 Passing a Tuple as Parameter

So far, if we needed to pass many parameters to a function, we wrote them after the name of the function and we separated them with empty spaces. Here is an example:

`let show x y z`

Such a format is referred to as curried form. Instead of applying different parameters to a function, you can pass a tuple that would act as a group of values. To do this, in place of one parameter, use a tuple; that is, one or more parameters inclosed in parentheses. Here is an example of a function that takes a pair:

`let calculateSalary(cmsRate, sales) = `

This format is referrred to as tuple form. After doing this, you can use the tuple or its elements in the body of the function. For example, you can refer to each parameter by its name and involve it in any statement or expression of your choice. Here is an example:

`let calculateSalary(cmsRate, sales) = cmsRate * sales / 100.00`

When calling the function, you must pass the tuple; that is, its arguments in parentheses. Here is an example:

```open System
open System.Drawing
open System.Windows.Forms

let compoundGrowth = new Form(Text = "Business Mathematics",
MaximizeBox = false,
ClientSize = new System.Drawing.Size(218, 140),
StartPosition = FormStartPosition.CenterScreen)

let lblPrincipal = new Label(AutoSize = true,
Text = "Principal:",
Location = new Point(23, 20))
let txtPrincipal = new TextBox(Location = new Point(118, 17),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))
let lblInterestRate = new Label(AutoSize = true,
Text = "Interest Rate:",
Location = new System.Drawing.Point(23, 46))
let txtInterestRate = new TextBox(Location = new Point(118, 44),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))
let lblPeriods = new Label(AutoSize = true,
Text = "Periods:",
Location = new Point(23, 74))
let txtPeriods = new TextBox(Location = new Point(118, 71),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))
let lblCompounded = new Label(AutoSize = true,
Text = "Compounded:",
Location = new Point(23, 100))
let txtCompounded = new TextBox(Location = new Point(118, 98),
Size = new System.Drawing.Size(83, 20))

let presentLoanDetails(principal, intRate, periods, compounded) =
txtPrincipal.Text <- string principal
txtInterestRate.Text <- string (sprintf "%0.02f%s" intRate "%")
txtPeriods.Text <- string periods
txtCompounded.Text <- compounded

presentLoanDetails(1500, 12.50, 4, "Monthly")

do System.Windows.Forms.Application.Run compoundGrowth```

Here is a test of the program: When passing a tuple to a function, if you want to specify the data type of an element, after its name, type : followed by its type. Here are examples:

```let calculateSalary(cmsRate : int, sales : float) = float cmsRate * sales / 100.00

let sales = 80.00
let commissionRate = 25 // %
let commissionEarned = calculateSalary(commissionRate, sales)

let presentLoanDetails(principal : int, intRate : float, periods, compounded : string) =
txtPrincipal.Text <- string principal
txtInterestRate.Text <- string (sprintf "%0.02f%s" intRate "%")
txtPeriods.Text <- string periods
txtCompounded.Text <- compounded```
 Passing Many Tuples

Instead of just one, you can pass as many tuple parameters as you need to a function. As done for parameters of primitive types, the tuple parameters are separated by an empty space (not a comma). Here is an example of a function that receives two triple tuples:

`let createEquations (a1, b1, c1) (a2, b2, c2) = . . .`

In the body of the function, you can then use the parameters as you see fit, and you can return any appropriate value. Here is an example of a function that takes two pairs and returns a string:

```open System
open System.Drawing
open System.Windows.Forms

let linearGemotry = new Form(Text = "Linear Geometry",
MaximizeBox = false,
ClientSize = new System.Drawing.Size(298, 160),
StartPosition = FormStartPosition.CenterScreen)

let rec gcd a b =
if b = 0 then
a
else
gcd b (a % b)

let createEquation (a1, b1) (a2, b2) =
let a = b1 - b2
let b = a2 - a1
let c = (a2 * b1) - (a1 * b2) // (a2 * b1) - (a1 * b1) - (a1 * b1) + (a1 * b2)

let mutable u = ""
let mutable v = ""
let mutable w = ""
let mutable absu = ""
let mutable absv = ""
let mutable absw = ""

if (a / (gcd a (gcd b c))) = 1 then
u <- ""
absu <- ""
else
u <- (string (abs (a / (gcd a (gcd b c)))))
absu <- (string (abs (a / (gcd a (gcd b c)))))

if (b / (gcd a (gcd b c))) = 1 then
v <- ""
absv <- ""
else
v <- (string (b / (gcd a (gcd b c))))
absv <- (string (abs (b / (gcd a (gcd b c)))))

if (c / (gcd a (gcd b c))) = 1 then
w <- ""
absw <- ""
else
w <- (string (abs (c / (gcd a (gcd b c)))))
absw <- (string (abs (c / (gcd a (gcd b c)))))

if (sign (a / (gcd a (gcd b c))) = -1) && (sign (b / (gcd a (gcd b c))) = 1) then
if (a / (gcd a (gcd b c))) = -1 then
"x - " + absv + "y = " + (string ((-1 * c) / (gcd a (gcd b c))))
else
absu + "x - " + absv + "y = " + (string ((-1 * c) / (gcd a (gcd b c))))
else
u + "x + " + v + "y = " + w

let lblIntroduction = new Label(AutoSize = true,
Text = "Equation of a line that goes through",
Location = new Point(25, 20))
let lblA = new Label(AutoSize = true,
Text = "A(",
Location = new System.Drawing.Point(22, 54))
let txtA1 = new TextBox(Location = new Point(38, 51),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(36, 20))
let lblComma1 = new Label(AutoSize = true,
Text = ",",
Location = new Point(80, 57))
let txtB1 = new TextBox(Location = new Point(96, 51),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(36, 20))
let lblB = new Label(AutoSize = true,
Text = ") and B(:",
Location = new Point(137, 54))
let txtA2 = new TextBox(Location = new Point(184, 51),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(36, 20))
let lblComma2 = new Label(Text = ",",
AutoSize = true,
Location = new Point(223, 57))
let txtB2 = new TextBox(Location = new Point(239, 51),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(36, 20))

let btnFind = new Button(Text = "Find",
Location = new Point(83, 87),
Size = new System.Drawing.Size(135, 23))

let lblEquation = new Label(AutoSize = true,
Text = "Equation:",
Location = new Point(22, 123))
let txtEquation = new TextBox(Location = new Point(80, 120),
Size = new System.Drawing.Size(138, 20))

let btnFindClick e =
let a1 = int txtA1.Text
let b1 = int txtB1.Text
let a2 = int txtA2.Text
let b2 = int txtB2.Text

let equation = createEquation (a1, b1) (a2, b2)
txtEquation.Text <- equation

do Application.Run linearGemotry

// let equation = createEquation (2, 3) (1, -4); // 7x - y = 11
// let equation = createEquation (-1, 5) (2, -4); // 3x + y = 2
// let equation = createEquation (1, 6) (3, 2); // 2x + y = 8
// let equation = createEquation (1, 3) (0, 1); // 2x - y = -1
// let equation = createEquation (4, 5) (3, 2); // 3x - y = 7
// let equation = createEquation (0, 4) (6, 0); // 2x + 3y = 12
// let equation = createEquation (-2, 3) (3, 8); // x - y = -5
// let equation = createEquation (-3, 3) (3, -1); // 4x + 6y =  6 => Reduced: 2x + 3y = 3
// let equation = createEquation (1, 6) (3, 2);   // 4x + 2y = 16 => Reduced: 2x + y = 8
// let equation = createEquation (3, 2) (7, -4);    // 6x + 4y = 26 => Reduced: 3x + 2y = 13
```

This would produce:  Combining Curried and Tuple Forms

As you know already, a function can take many arguments in curried form. In the same way, a function can take one or more tuples as parameters and each parameter would be a tuple. In this case, each tuple parameter must use its own parantheses that include its elements.

A function can takes parameters in a combination of curried and tuple forms. Each tuple must include its own parentheses while the other parameters would appear without parentheses. Of course, the parameters are separaters only by space. Here is an example:

`let calculateCommissionSalary sales (bsCmsRate, bsSales) abvBaseSalesRate = ...`

In the body of the function, you can access any parameter, including any element of the tuple parameter, using its name. When calling the function, you must pass the tuple in the same placeholder where it is indicated on the function definition. Here is an example:

```let calculateCommissionSalary sales (bsCmsRate, bsSales) abvBaseSalesRate =
if sales <= bsSales then
sales * bsCmsRate / 100.00
else
let startSales = bsSales * bsCmsRate / 100.00
let endSales = (sales - bsSales) * abvBaseSalesRate / 100.00
startSales + endSales

let totalSales = 1200.00
let firstPortionLimit = 800.00
let firstPortionCommissionRate = 25.00
let commissionRateAboveFirstPortion = 10.00
let earnings = calculateCommissionSalary totalSales (firstPortionCommissionRate, firstPortionLimit) commissionRateAboveFirstPortion
```

In its immense flexibility combined with the fact that it is an infered language, F# allows you to specify any parameters just by its name. Consider the following example:

`let calculateCommissionSalary sales commission abvBaseSalesRate =`

In this case, each parameter is simply positioned in a placeholder, and each parameter can be anything. This means that a parameter that is represented with one word can as well be a tuple. If a parameter is a tuple, in the body of the function, declare some variables that would each represent a part of the tuple parameter, and assing that parameter to it. You can then use the variables as if they were passed to the function. Here is an example:

```let calculateCommissionSalary sales commission abvBaseSalesRate =
let (bsCmsRate, bsSales) = commission

if sales <= bsSales then
sales * bsCmsRate / 100.00
else
let startSales = bsSales * bsCmsRate / 100.00
let endSales = (sales - bsSales) * abvBaseSalesRate / 100.00
startSales + endSales```

When calling the function, every parameter that represents a tuple must be passed as such; that is, include the arguments in the parentheses in the place of the tuple parameter, exactly as we did above.

You can pass tuples of different dimensions. You can also pass different types of tuples and regular parameters. Here is an example:

`let doSomething (a, b) (d, e, f) something = . . .`

In this case, you are creating a function that is receiving two tuples (one pair and one triple) and one parameter of any kind.

Remember that, when creating a function that takes many parameters, each parameter occupies a position and the parameter can be anything. In fact, you can pass many parameters in curried form or one parameter as a tuple and each parameter would represent its own tuple. Consider the following example:

`let prepareBill(first, second, third, more, consumption) = . . .`

Any one of these parameters can be treated as a tuple in the body of the function. In this example, let's consider "first" as a tuple. In the body of the function, you can declare a variable that is a tuple with names of elements, and initialize that variable with a parameter that is a tuple. You can then use the names of the elements as if they were actual variables. Here is an example of a function that takes three tuples (each a pair) and two floating point values:

```let prepareBill(first, second, third, more, consumption) =
let (a, b) = first
let (c, d) = second
let (e, f) = third

if consumption <= b then
consumption * a
elif consumption <= d then
consumption * c
elif consumption <= f then
consumption * e
else
consumption * more

let total1 = prepareBill ((0.7458, 50.00), (0.5866, 75.00), (0.3274, 105.00), 0.2864, 46.32)
let total2 = prepareBill ((0.7458, 50.00), (0.5866, 75.00), (0.3274, 105.00), 0.2864, 68.14)
let total3 = prepareBill ((0.7458, 50.00), (0.5866, 75.00), (0.3274, 105.00), 0.2864, 93.27)
let total4 = prepareBill ((0.7458, 50.00), (0.5866, 75.00), (0.3274, 105.00), 0.2864, 148.58)
```

When creating the function, if you want to indicate that a parameter is a tuple, you can specify its data types. To do this, after the name of a parameter, type a colon followed by the types of parameters separated from each other by *. Here are example:

`let prepareBill(first : float * float, second : float * float, third : float * float, more, consumption) = . . .`

As an alternative, you can put the types in parentheses. Here is an example:

`let prepareBill(first : (float * float), second : (float * float), third : (float * float), more, consumption) = . . .`

Based on the ability to pass one-word parameters to a function and treat such parameters as tuples, the F# language provides tremendous flexibility. For example, you can pass a single parameter to a function but that parameter can carry as many values as you want, thanks to the features of tuples. Consider the following example:

`let prepareBill invoice = . . .`

If you pass a parameter that is carrying many internal values, in the body of the function, to segment the parameter in the appropriate individual values, you can first declare a variable for a tuple and initialize that tuple with the parameter. Here is an example:

```let prepareBill invoice =
// Breaking the argument in the number of desired parts
let (first, second, third, more, consumption) = invoice```

From there, you can further segment each member of the new tuple to get the desired values. Here is an example:

```let prepareBill invoice =
// Breaking the argument in the number of desired parts
let (first, second, third, more, acntBr, consumption, state) = invoice
// Using each part to get its value
let (a, b) = first
let (c, d) = second
let (e, f) = third

if consumption <= b then
consumption * a
elif consumption <= d then
consumption * c
elif consumption <= f then
consumption * e
else
consumption * more

let customerAccountNumber = "203-840-384"
let stateResidence = "MD"
let total = prepareBill ((1.3779, 45.50), (0.9607, 84.65), (0.5258, 112.85), 0.2864, customerAccountNumber,  122.74, stateResidence)
```

Of course, you can specify the data types of the parameters using the appropriate parentheses where necessary. Here is an example:

```let prepareBill (invoice : (float * float) * (float * float) * (float * float) * float * string * float * string) =
. . .```
 Returning a Value Off a Tuple

When a tuple is passed as parameter, the function can use the tuple or its elements as it sees fit. For example, the function can perform operations on the elements of the tuple and then return the result. Here is an example that takes a tuple as parameter, calculates a new number on the elements of that tuple and returns the result as a constant value:

```open System
open System.Drawing
open System.Windows.Forms

let compoundGrowth = new Form(Text = "Business Mathematics",
MaximizeBox = false,
ClientSize = new System.Drawing.Size(218, 170),
StartPosition = FormStartPosition.CenterScreen)

let calculate(principal, payingRate, periods) =
principal * ((1.00 + (payingRate / periods)) ** (12.00 * periods))

let lblPrincipal = new Label(AutoSize = true,
Text = "Amount to Invest:",
Location = new Point(23, 20))
let txtPrincipal = new TextBox(Location = new Point(118, 17),
Size = new System.Drawing.Size(75, 20))
let lblPayingRate = new Label(AutoSize = true,
Text = "Paying Rate:",
Location = new System.Drawing.Point(23, 46))
let txtPayingRate = new TextBox(Location = new Point(118, 44),
Size = new System.Drawing.Size(60, 20))
let lblPercentSign = new Label(AutoSize = true,
Text = "%",
Location = new Point(180, 46))
let lblPeriods = new Label(AutoSize = true,
Text = "Periods:",
Location = new Point(23, 74))
let txtPeriods = new TextBox(Location = new Point(118, 71), Size = new System.Drawing.Size(75, 20))

let btnCalculate = new Button(Text = "Calculate",
Location = new Point(118, 98),
Size = new System.Drawing.Size(75, 23))

let lblPayingAmount = new Label(AutoSize = true,
Text = "Paying Amount:",
Location = new Point(23, 140))
let txtCompoundedGrowth = new TextBox(Location = new Point(118, 128), Size = new System.Drawing.Size(75, 20))

let btnCalculateClick (e : EventArgs) =
let mutable principal = 0.00
let mutable rate = 0.00
let mutable periods = 0.00

try
principal <- float txtPrincipal.Text

with
| :? FormatException as exc -> MessageBox.Show("The value you provided for the principal is not a valid number", "Compunded Growth",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore;
try
rate <- float txtPayingRate.Text

with
| :? FormatException as exc -> MessageBox.Show("The value you provided for the paying rate is not a valid number", "Compunded Growth",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore;
try
periods <- float txtPeriods.Text

with
| :? FormatException as exc -> MessageBox.Show("The value you provided for the periods is not a valid number", "Compunded Growth",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore;

let result = calculate(principal, rate, periods)
txtCompoundedGrowth.Text <- sprintf "%0.02f" result

do System.Windows.Forms.Application.Run compoundGrowth```

Remember that you can specify the return type of a function before its = sign. Here is an example:

```let calculate(principal, payingRate, periods) : float =
principal * ((1.00 + (payingRate / periods)) ** (12.00 * periods))```
 Returning a Tuple

A function can receive regular values, manipulate them, and then return a tuple. Here is an example of a function that gets one value as parameter and returns a triple:

```let calculations a =
let x = sin a;
let y = cos a;
let z = tan a;
(x, y, z);```

You can then access the returned type as one value. Here is an example:

```open System
open System.Drawing
open System.Windows.Forms

let trigonometry = new Form(Text = "Date Values",
MaximizeBox = false,
ClientSize = new System.Drawing.Size(528, 55),
StartPosition = FormStartPosition.CenterScreen)

let calculate number =
let x = sin number
let y = cos number
let z = tan number
(x, y, z)

let lblValues = new Label(AutoSize = true,
Text = "(Sine, Cosine, Tangent) of 45.00 =",
Location = new Point(12, 20))

let txtValues = new TextBox()
txtValues.Location <- new Point(188, 17)
txtValues.Size <- new System.Drawing.Size(320, 20)

let sct = calculate 45.00
txtValues.Text <- string sct

do Application.Run trigonometry```

This would produce: To specify that a function is returning a tuple, before its = sign, type a colon followed by the types of its return tuple. The types must be separated by * from each other. Here is an example:

```let calculate number : float * float * float =
let x = sin number
let y = cos number
let z = tan number
(x, y, z)```
 Tuples and Function Values

If you create a function that takes one or more function values as arguments, you can make the function return a tuple that holds different values from the function value(s). Here is an example:

```let add2Values a b = a + b
let multiply3Values a b c = a * b * c

let calculateInterest (state : float -> float -> float -> float) (totalize : float -> float -> float) printcipal rate periods =
let totalInterest = state printcipal rate periods
let futureValue = totalize printcipal totalInterest
(totalInterest, futureValue)

let interest, future = calculateInterest multiply3Values add2Values 1750.00 (10.25/100.00) 2.00
```

The body of the function could have the following:

```let calculateInterest (state : float -> float -> float -> float) (totalize : float -> float -> float) printcipal rate periods =
let totalInterest = state printcipal rate periods
let futureValue = totalize printcipal (state printcipal rate periods)
(totalInterest, futureValue)```

Remember that if you are not planning to use the return value of a function value many times, you don't have to store it first in a variable. You can just call it where it is needed. Here are examples that apply to returning a tuple:

```let add2Values a b = a + b
let multiply3Values a b c = a * b * c

let calculateInterest (state : float -> float -> float -> float) (totalize : float -> float -> float) printcipal rate periods =
(state printcipal rate periods, totalize printcipal (state printcipal rate periods))

let interest, future = calculateInterest multiply3Values add2Values 1750.00 (10.25/100.00) 2.00
```

 Operations on Tuples

 Introductory Built-In Operators

To assist you with various types of operations on tuples and their items, the F# language provides a series of operators and built-in functions that can be applied directly to the members of a tuple.

A tuple has built-in functionality to perform all operations using regular algebraic operators:

• The addition is used to add the members of a tuple. This operation can be performed on numbers or strings. Here is an example:
`let addition(a, b, c) = a + b + c`
• If the members of a tuple are numeric values, you can perform the subtraction (-), the division (/), or the multiplication (*) operation on them. Here is an example that performs the multiplication:
`let multiplication(a, b) = a * b`
If the tuple contains values that don't support the subtraction, the division, or the multiplication, like strings, don't perform that operation. Otherwise you would receive an error
• The % operator is used to find the remainder of a division of both numbers of a pair. Here is an example:
`let modulo(a, b) = a % b`
This operator cannot be applied to non-numeric values
• If you have a numeric pair, to find the power of one member raised to the other member, use the ** operator. Here is an example:
`let power(a, b) = a ** b`
This operator can be applied only to decimal numbers
• The Boolean operators can be applied to two members of a tuple to perform comparisons on them. Remember that the Boolean operators are: =, <, <=, >, >=, and <>. Here is an example:
`let comparison(a, b) = a < b`
• Bit-based operations are available on the members of a tuple. The &&& operator is used to perform the bitwise AND operation on two members of the tuple. Other available operators are <<<, >>>, ^^^.

In the same way, you can perform all types of operations on the members of . Here is an example:

```open System
open System.Drawing
open System.Windows.Forms

let financialDecisionMaking = new System.Windows.Forms.Form(Text = "Business",
MaximizeBox = false,
ClientSize = new System.Drawing.Size(218, 150),
StartPosition = FormStartPosition.CenterScreen)

let (currentAssets, inventory, currentLiatilities) = (4841586.00, 682400.00, 2115351.00)

let lblCurrentAssets = new System.Windows.Forms.Label(AutoSize = true,
Text = "Current Assets:",
Location = new Point(23, 20))

let txtCurrentAssets = new System.Windows.Forms.TextBox(Text = string currentAssets,
Location = new Point(118, 17),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))

let lblInventory = new System.Windows.Forms.Label(AutoSize = true,
Text = "Inventory:",
Location = new System.Drawing.Point(23, 46))

let txtInventory = new System.Windows.Forms.TextBox(Text = string inventory,
Location = new Point(118, 44),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))

let lblCurrentLiabilities = new System.Windows.Forms.Label(AutoSize = true,
Text = "Current Liabilities:",
Location = new Point(23, 74))

let txtCurrentLiabilities = new System.Windows.Forms.TextBox(Text = string currentAssets,
Location = new Point(118, 71),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))

let lblLine = new System.Windows.Forms.Label(BackColor = System.Drawing.Color.Black,
Size = new System.Drawing.Size(176, 1),
Location = new System.Drawing.Point(25, 99))

let lblQuickRatio = new System.Windows.Forms.Label(AutoSize = true,
Text = "Quick Ratio:",
Location = new System.Drawing.Point(23, 111))

let txtQuickRatio = new System.Windows.Forms.TextBox(Location = new Point(118, 109),
TextAlign = HorizontalAlignment.Right,
Size = new System.Drawing.Size(83, 20))
txtQuickRatio.Text <- string (sprintf "%0.03f" ((currentAssets - inventory) / currentLiatilities))

do System.Windows.Forms.Application.Run financialDecisionMaking```

This would produce: Applying a Pair to a Function

If you create a function in curried form that takes two parameters, when calling the function, you can pass its arguments as a tuple. This is referred to as applying a tuple to a function.

To apply two values to a function, applying the values as a pair, use the <|| operator. The formula to follow is:

`Function <|| (Value1, Value2)`

The values are included in parentheses on the right side of the operator. Here is an example: The debt ratio is the relationship between the total liabtilities of a company and the total assets it posses. The debt ratio is dividing the total debt by the total assets.
```open System
open System.Drawing
open System.Windows.Forms

let debtRatio = new Form(Text = "Dept Ratio",
MaximizeBox = false,
ClientSize = new System.Drawing.Size(222, 156),
StartPosition = FormStartPosition.CenterScreen)

let calculate debt assets = debt / assets

let lblTotalDebt = new Label(AutoSize = true,
Text = "Total Debt:",
Location = new Point(22, 24))
let txtTotalDebt = new TextBox(Location = new Point(123, 21),
Size = new System.Drawing.Size(75, 20))
let lblTotalAssets = new Label(AutoSize = true,
Text = "Total Assets:",
Location = new Point(22, 54))
let txtTotalAssets = new TextBox(Location = new Point(123, 51),
Size = new System.Drawing.Size(75, 20))

let btnCalculate = new Button(Text = "Calculate",
Location = new Point(123, 82),
Size = new System.Drawing.Size(75, 23))
let lblDebtRatio = new Label(AutoSize = true,
Text = "Debt Ratio:",
Location = new System.Drawing.Point(23, 118))
let txtDebtRatio = new TextBox(Location = new Point(123, 115),
Size = new System.Drawing.Size(75, 20))

let btnCalculateClick (e : EventArgs) =
let mutable totalDebt = 0.00
let mutable totalAssets  = 0.00

try
totalDebt <- float txtTotalDebt.Text

with
| :? FormatException as exc -> MessageBox.Show("The value you provided for the total debt is not valid", "Debt Ratio",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore;

try
totalAssets <- float txtTotalAssets.Text

with
| :? FormatException as exc -> MessageBox.Show("The value you provided for the total assets is not valid", "Debt Ratio",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore;

let result = calculate <|| (totalDebt, totalAssets)
txtDebtRatio.Text <- sprintf "%0.02f%s" (result * 100.00) "%"

do System.Windows.Forms.Application.Run debtRatio```

This would produce: You can also apply one value to the left of the function and a pair to the right of the function.

The alternative is to use the ||> in which case the positions of the function and the values in parentheses are inversed. Here is an example:

```let btnCalculateClick (e : EventArgs) =
let mutable totalDebt = 0.00
let mutable totalAssets  = 0.00

try
totalDebt <- float txtTotalDebt.Text

with
| :? FormatException as exc -> MessageBox.Show("The value you provided for the total debt is not valid", "Debt Ratio",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore;

try
totalAssets <- float txtTotalAssets.Text

with
| :? FormatException as exc -> MessageBox.Show("The value you provided for the total assets is not valid", "Debt Ratio",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore;

let result = (totalDebt, totalAssets) ||> calculate
txtDebtRatio.Text <- sprintf "%0.02f%s" (result * 100.00) "%"```
 Applying a Triple to a Function

To apply three values to a function, use the <||| operator. The formula to use is:

`Function <||| (Value1, Value2, Value3)`

The function is in curried form and takes three parameters. When calling the function, use the <||| operator but pass the arguments as a triple. Here is an example:

```let getFullName a b c = a + " " + b + " " + c
let fullName = getFullName <||| ("Jean", "Philippe", "Marthely")```

An alternative is to use the |||> operator. In this case, the values and their parentheses must appear first (to the left of the operator) while the function must appear to the right.

 Applying a Tuple to a Function

When studying functions, we saw how you can apply a value to a function. In reality, such a a value can be a tuple. This allows you to apply a single value that happens to hold many sub-values.

 Pattern Matching and Tuples

 Introduction

Consider the following tuple:

`let numbers = (1, 4, 6, 12, 36)`

If you create such a tuple where you don't name the members and simply assign that tuple to a variable, there is no tuple built-in operator to access each member. A solution is to use pattern matching. To use it, create a matching pattern with one case. The case must have the same number of elements as the tuple. In the tuple, create a name for each element. The name can be a letter or any word that follows the rules for names in F#. The case is followed by -> and what you want to do. From there, you can access each value of the tuple using its corresponding name in the matching case. Here is an example:

```let numbers = (1, 4, 6, 12, 36)
match numbers with
| (one, four, six, twelve, thirtySix) -> printfn "Numbers: %d, %d, %d, %d, %d" one four six twelve thirtySix```

Of course, you can consider any of the names in the case as a value and use it any way you want. Here is an example:

```let numbers = (1, 4, 6, 12, 36)
match numbers with
| (one, four, six, twelve, thirtySix) ->
let number = twelve * 2```
 Pattern Matching and Parameters

One of the striking features of tuples is that a parameter can be passed with a simple name to a function. That function can treat the parameter as a tuple. As a consequence, a single parameter can carry as many values as possible. In the body of the function, you retrieve values from the parameter. One way you can do this is with pattern matching. This can be done as follows:

```let calculate(schedule) =
match schedule with
| value1, value2, value3, value4 -> . . .```

In the same way, you pass as many parameters as possible and any of them can be treated as a tuple that carries many values. When calling the function, you must provide the appropriate number of values for each parameter. The values of a parameter used as tuple should be passed in their own paratheses. Here is an example: Some companies that sell stocks evaluate the investment by the number of shares that a person buys. When buying, a person is presented with values of different companies or businesses. A typical share has a value. A customer who is interested in the values of a certain company can then purchase a certain number of share. The share principal is calculated by multiplying the number of shares that a person bought by the price per share. The company may use a table named a commission schedule as follows:

 Commission Schedule If the Principal is Between and Pay 0 2499 28.50 + 1.65% of Principal 2500 5999 55.75, 1.05 of Principal 6000 19999 65.85, 0.75 of Principal 20000 49999 80.00, 0.35 of Principal 50000 499999 145.50, 0.15 of Principal 500000 Above 225.00, 0.05 of Principal

```open System
open System.Drawing
open System.Windows.Forms

MaximizeBox = false,
ClientSize = new System.Drawing.Size(222, 156),
StartPosition = FormStartPosition.CenterScreen)

let calculate(schedule1, schedule2, schedule3, schedule4, schedule5, schedule6, shares, price) =
let principal = shares * price
let mutable commission = 0.00

match schedule1 with
| a1, a2, a3, a4 ->
if (principal >= a1) && (principal <= a2) then
commission <- a3 + (principal * a4 / 100.00)
match schedule2 with
| b1, b2, b3, b4 ->
if (principal >= b1) && (principal <= b2) then
commission <- b3 + (principal * b4 / 100.00)
match schedule3 with
| c1, c2, c3, c4 ->
if (principal >= c1) && (principal <= c2) then
commission <- c3 + (principal * c4 / 100.00)
match schedule4 with
| d1, d2, d3, d4 ->
if (principal >= d1) && (principal <= d2) then
commission <- d3 + (principal * d4 / 100.00)
match schedule5 with
| e1, e2, e3, e4 ->
if (principal >= e1) && (principal <= e2) then
commission <- e3 + (principal * e4 / 100.00)
match schedule6 with
| f1, f2, f3 ->
if principal >= f1 then
commission <- f2 + (principal * f3 / 100.00)
principal + commission

let lblNumberOfShares = new Label(AutoSize = true,
Text = "Number of Shares:",
Location = new Point(22, 24))
let txtNumberOfShares = new TextBox(Location = new Point(123, 21),
Size = new System.Drawing.Size(75, 20))
let lblPricePerShare = new Label(AutoSize = true,
Text = "Price Per Share:",
Location = new Point(22, 54))
let txtPricePerShare = new TextBox(Location = new Point(123, 51),
Size = new System.Drawing.Size(75, 20))

let btnCalculate = new Button(Text = "Calculate",
Location = new Point(123, 82),
Size = new System.Drawing.Size(75, 23))
let lbltotalInvestment = new Label(AutoSize = true,
Text = "Total Investment:",
Location = new System.Drawing.Point(23, 118))
let txttotalInvestment = new TextBox(Location = new Point(123, 115),
Size = new System.Drawing.Size(75, 20))

let btnCalculateClick (e : EventArgs) =
let mutable numberofShares = 0.00
let mutable pricePerShare  = 0.00

try
numberofShares <- float txtNumberOfShares.Text

with
| :? FormatException as exc -> MessageBox.Show("The value you provided for the number of shares is not correct", "Stock Trade",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore;

try
pricePerShare <- float txtPricePerShare.Text

with
| :? FormatException as exc -> MessageBox.Show("The value you provided for the price per share is not correct", "Stock Trade",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore;

let result = calculate((     0.00,   2499.00,  28.50, 1.65),
(  2500.00,   5999.00,  55.75, 1.05),
(  6000.00,  19999.00,  65.85, 0.75),
( 20000.00,  49999.00,  80.00, 0.35),
( 50000.00, 499999.00, 145.50, 0.15),
(500000.00,            225.00, 0.05),
numberofShares, pricePerShare)
txttotalInvestment.Text <- sprintf "%0.02f" result

If. Here is an example: Tuples and Records

 A Tuple of Record Objects

A member of a tuple can be of a record type. Before creating the tuple, you should (must) first create the record type and an object from it. When creating the tuple, add the record object in the placeholder in the parentheses. The combinations are up to you:

• You can create a tuple that has one or more members based on a record and the other members of primitive types. Here is an example of a tuple whose elements are a natural number, a record object, and a string:
```type OccupancyStatus =
| Other       = 0
| Available   = 1
| Occupied    = 2
| NeedsRepair = 3

type Apartment = {
UnitNumber      : string
Bedrooms        : int
Bathrooms       : float
SecurityDeposit : int
MonthlyRate     : int
Status          : OccupancyStatus }

let a508293 = { UnitNumber = "102"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit = 500; MonthlyRate =  950; Status = OccupancyStatus.NeedsRepair }
let contract = (10001, a508293, "08/30#2015")```
• You can create a tuple whose all elements are of the same record. Here is an example:
```type Student = {
StudentNumber : int
FirstName     : string
LastName      : string
Gender        : char }

let std920817 = {
StudentNumber = 920817
FirstName     = "Roland"
LastName      = "Purcell"
Gender        = 'M' }

let std274958 = {
StudentNumber = 274958
FirstName     = "Josianne"
LastName      = "Ballam"
Gender        = 'F' }

• You can create a tuple whose elements are a combination of objects of different records. Here is an example:
```type MusicalInstrument = {
ItemNumber      : int
ItemName        : string
MonthlyRent     : float }

type Customer = {
AccountNumber : int
CustomerName  : string }

let mi = { ItemNumber = 930485; ItemName = "Roland JUNO-Gi Synthesizer"; MonthlyRent = 28.50 }
let client = { AccountNumber = 66102; CustomerName = "Jonathan Moella" }
let rent = (mi, client)```
• You can create a tuple whose elements are combinations of record objects and values of primitive types. Here is an example:
```type MusicalInstrument = {
ItemNumber      : int
ItemName        : string
MonthlyRent     : float }

type Customer = {
AccountNumber : int
CustomerName  : string }

let mi = { ItemNumber = 930485; ItemName = "Roland JUNO-Gi Synthesizer"; MonthlyRent = 28.50 }
let client = { AccountNumber = 66102; CustomerName = "Jonathan Moella" }

let contract = (1001, mi, client, "04/30/2015")```

After creating the tuple, you can access it as one object. If you want to access the individual elements of the tuple, you can use a matching pattern whose case would provide a name in the placeholder of each element. Once you get to the record object, you can access its members and use them as you see fit. Here is an example:

```open System
open System.Drawing
open System.Windows.Forms

type Customer = {
AccountNumber : string
CustomerName  : string

let client = {
AccountNumber = "2048-5094"
CustomerName  = "Victorine Barrett"
HomeAddress   = "14808 Executive Blvd, Rockville, MD 20853" }

let prepareBill(first, second, third, consumption) =
let (a, b) = first
let (c, d) = second

if consumption <= b then
consumption * a
elif consumption <= d then
consumption * c
else
consumption * third

// Dialog Box: Gas Utility Company - Customer Bill Summary
let gasUtilityCompanyBillPreparation : Form = new Form(MaximizeBox = false,
MinimizeBox = false,
Text = "Gas Utility Company",
FormBorderStyle = FormBorderStyle.FixedDialog,
ClientSize = new System.Drawing.Size(214, 112),
StartPosition = FormStartPosition.CenterScreen)

// Label: Account Number
let lblBillPreparationAccountNumber = new Label(AutoSize = true,
Text = "Account #:",
Location = new System.Drawing.Point(20, 16))

// Text Box: Account Number
let txtBillPreparationAccountNumber = new TextBox(Size = new System.Drawing.Size(75, 20),
Location = new System.Drawing.Point(122, 13))

// Label: CCF Consumption
let lblBillPreparationCCFConsumption = new Label(AutoSize = true,
Text = "CCF Consumption:",
Location = new System.Drawing.Point(22, 45))

// Text Box: CCF Consumption
let txtBillPreparationCCFConsumption = new TextBox(Size = new System.Drawing.Size(75, 20),
Location = new System.Drawing.Point(122, 42))

// ----------------------------------------------------------------------------------------------
// Form: Gas Utility Company - Customer Bill Summary
let gasUtilityCompany : Form = new Form(MaximizeBox = false,
Text = "Gas Utility Company - Bill Summary",
ClientSize = new System.Drawing.Size(362, 202),
StartPosition = FormStartPosition.CenterScreen)

// Label: Bill Number
let lblBillNumber = new Label(Text = "Bill #:",
AutoSize = true,
Location = new Point(18, 18))

// Text Box: Bill Number
let txtBillNumber = new TextBox(Size = new System.Drawing.Size(75, 20),
Location = new System.Drawing.Point(118, 15))

// Label: Account Number
let lblAccountNumber = new Label(AutoSize = true,
Text = "Account #:",
Location = new System.Drawing.Point(18, 44))

// Text Box: Account Number
let txtAccountNumber = new TextBox(Size = new System.Drawing.Size(75, 20),
Location = new System.Drawing.Point(118, 44))

// Label: Customer Name
let lblCustomerName = new Label(AutoSize = true,
Text = "Customer Name:",
Location = new System.Drawing.Point(18, 70))

// Text Box: Customer Name
let txtCustomerName = new TextBox(Size = new System.Drawing.Size(160, 20),
Location = new System.Drawing.Point(118, 67))

let lblHomeAddress = new Label(AutoSize = true,
Location = new System.Drawing.Point(18, 96))

let txtHomeAddress = new System.Windows.Forms.TextBox(Size = new System.Drawing.Size(224, 20),
Location = new System.Drawing.Point(118, 96))
// Label: Line
let lblLine = new Label(BackColor = Color.Black,
Location = new System.Drawing.Point(20, 127),
Size = new System.Drawing.Size(322, 1))

// Label: CCF Consumption
let lblCCFConsumption = new Label(AutoSize = true,
Text = "CCF Consumption:",
Location = new System.Drawing.Point(18, 144))

// Text Box: CCF Consumption
let txtCCFConsumption = new TextBox(Size = new System.Drawing.Size(75, 20),
Location = new System.Drawing.Point(118, 141))

// Label: Amount Due
let lblAmountDue = new Label(AutoSize = true,
Text = "Amount Due:",
Location = new System.Drawing.Point(201, 144))
// Text Box: Amount Due
let txtAmountDue = new TextBox(Location = new Point(277, 141),
Size = new System.Drawing.Size(65, 20))

// Button: Close
let btnClose = new Button(Text = "Close",
Location = new System.Drawing.Point(267, 172))
let btnCloseClick e = gasUtilityCompany.Close()

gasUtilityCompanyBillPreparation.ShowDialog() |> ignore

// Button: Evaluate
let btnEvaluate = new Button(Text = "Evaluate", Location = new System.Drawing.Point(122, 77))

let btnEvaluateClick e =
let mutable consumption = 0.00

if String.IsNullOrEmpty txtBillPreparationAccountNumber.Text then
MessageBox.Show("You must enter a customer account number", "Gas Utility Company",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore

if String.IsNullOrEmpty txtBillPreparationCCFConsumption.Text then
MessageBox.Show("You must enter the amount of gas the customer used", "Gas Utility Company",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore

let acntNumber = txtBillPreparationAccountNumber.Text

try
consumption <- float txtBillPreparationCCFConsumption.Text

with
| :? FormatException as exc -> MessageBox.Show("The amount of gas consumption you provided is not a valid number", "Gas Utility Company",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore

if acntNumber = client.AccountNumber then
let bill = (100001, client, consumption)

match bill with
| (nbr, payer, cons) ->
txtBillNumber.Text <- string nbr
txtAccountNumber.Text <- payer.AccountNumber
txtCustomerName.Text <- payer.CustomerName
txtCCFConsumption.Text <- sprintf "%0.02f" cons

let amtDue = prepareBill ((0.7458, 50.00), (0.5866, 150.00), 0.3582, consumption)
txtAmountDue.Text <- sprintf "%0.02f" amtDue

(* The following would work also
let (a, b, c) = (100001, client, consumption)

txtBillNumber.Text <- string a

txtAccountNumber.Text <- b.AccountNumber
txtCustomerName.Text <- b.CustomerName

txtCCFConsumption.Text <- sprintf "%0.02f" c
let amtDue = prepareBill ((0.7458, 50.00), (0.6566, 150.00), 0.5824, consumption)
txtAmountDue.Text <- sprintf "%0.02f" amtDue*)
else
MessageBox.Show("There is no customer with that account number", "Gas Utility Company",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore
gasUtilityCompanyBillPreparation.Close()

[<EntryPoint>]
let main argv =
Application.Run gasUtilityCompany
0 // return an integer exit code```

This would produce:  A Tuple in a Record

A member of a record can be a tuple. To create the member, provide its name and specify its data type as a combination of types that are separated by *. Here is an example:

```type RentalContract = {
ContractNumber    : int
MusicalInstrument : int * string * float }```

When creating the object for the record, assign the value of a tuple member as you would for a variable. Here are examples:

```type RentalContract = {
ContractNumber    : int
ProcessedBy       : string * string
MusicalInstrument : int * string * float
Customer          : int * string * string * char
RentStartDate     : string }

let contract = {
ContractNumber    = 100001
ProcessedBy       = ("2036-4950", "Joshua Melmann")
MusicalInstrument = (930485, "Roland JUNO-Gi Synthesizer", 1.25)
Customer          = (29374, "Rebecca", "Mewes", 'F')
RentStartDate     = "06/12/2015" }```

You can then access each member of the object. Remember that you can use a matching pattern to access each member of a tuple.

 Tuples and Classes

 A Tuple of Objects

Each member of a tuple can be of any type, including a class or structure. When creating the tuple, you can first create each object. In the tuple, use the name of the object in the desired placeholder. Here is an example:

```type Employee(nbr, name) =
let mutable n = nbr
let mutable m = name
member this.EmployeeNumber with get() = n and set(value) = n <- value
member this.FullName with get() = m and set(value) = m <- value

type FoodItem(code, name, price) =
let mutable cd = code
let mutable nm = name
let mutable pr = price
member this.ItemCode with get() = cd and set(value) = cd <- value
member this.FoodName with get() = nm and set(value) = nm <- value
member this.UnitPrice with get() = pr and set(value) = pr <- value

let clerk = Employee(60284, "Frank Evers")
let food = FoodItem("LS01", "Sweet and Sour Chicken", "5.95")

let order = (clerk, food)```

You don't have to first create the objects outside the tuple. You can create the objects directly in the tuple. Here is an example:

`let order = (Employee(60284, "Frank Evers"), FoodItem("LS01", "Sweet and Sour Chicken", "5.95"))`

You can access the members of the tuple as we have done so far. If you want to access each member, you can create a matching pattern. From the option, the first member of the case represents the class of the first element of the tuple. This means that the first member of the case gives you access to the members of the class of the first element. The second element of the case gives you access to the members of the class of the second object, and so on. Here is an example:

```type Employee(nbr, name) =
let mutable n = nbr
let mutable m = name
member this.EmployeeNumber with get() = n and set(value) = n <- value
member this.FullName with get() = m and set(value) = m <- value

type FoodItem(code, name, price) =
let mutable cd = code
let mutable nm = name
let mutable pr = price
member this.ItemCode with get() = cd and set(value) = cd <- value
member this.FoodName with get() = nm and set(value) = nm <- value
member this.UnitPrice with get() = pr and set(value) = pr <- value

let order = (Employee(60284, "Frank Evers"), FoodItem("LS01", "Sweet and Sour Chicken", 5.95))
```

You can create groups for each class by including the appropriate members in individual tuples and access them like that. Because the class members are identifiable, you can access each by its name and use it as you see fit.

In the same way, you can create a tuple that has as many objects as you want, and you can use a combination of objects and values of primitive types in a tuple. If you want to specify the type of each member of the tuple, after the name of the variable, type : followed by the types separated by *. Here is one example:

```type Employee(nbr, name) =
let mutable n = nbr
let mutable m = name
member this.EmployeeNumber with get() = n and set(value) = n <- value
member this.FullName with get() = m and set(value) = m <- value

type FoodItem(code, name, price) =
let mutable cd = code
let mutable nm = name
let mutable pr = price
member this.ItemCode with get() = cd and set(value) = cd <- value
member this.FoodName with get() = nm and set(value) = nm <- value
member this.UnitPrice with get() = pr and set(value) = pr <- value

let clerk = Employee(60284, "Frank Evers")
let food = FoodItem("LS01", "Sweet and Sour Chicken", "5.95")

let order : Employee * FoodItem = (clerk, food)```

Here is another example:

```type Employee(nbr, name) =
let mutable n = nbr
let mutable m = name
member this.EmployeeNumber with get() = n and set(value) = n <- value
member this.FullName with get() = m and set(value) = m <- value

type FoodItem(code, name, price) =
let mutable cd = code
let mutable nm = name
let mutable pr = price
member this.ItemCode with get() = cd and set(value) = cd <- value
member this.FoodName with get() = nm and set(value) = nm <- value
member this.UnitPrice with get() = pr and set(value) = pr <- value

let order : int * string * Employee * FoodItem * float = (1001, "06/18/2015", Employee(60284, "Frank Evers"), FoodItem("LS01", "Sweet and Sour Chicken", 5.95), 15.00)```
 Returning a Tuple From a Method

A method of a class can return a method when it has performed its action. The method can be passed its own parameter(s) or it can use (a) parameter(s) from a constructor. Here are examples:

```open System
open System.Drawing
open System.Windows.Forms

type TimeSheet(salary, mon, tue, wed, thu, fri, sat, sun) =
let sal = ref salary

let overtimeSalary = !sal * 1.50

member this.HourlySalary with get() = !sal and set(value) = sal := value

// Returning a Tuple from a method
member this.GetMondaySummary() =
let regTime =
if mon <= 8.00 then
mon
else
8.00
let overTime =
if mon <= 8.00 then 0.00
else mon - 8.00
let regPay = regTime * !sal
let overPay = overTime * overtimeSalary
(regTime, overTime, regPay, overPay)

member this.GetTuesdaySummary() =
let regTime = if tue <= 8.00 then tue else 8.00
let overTime = if tue <= 8.00 then 0.00 else tue - 8.00
let regPay = (if tue <= 8.00 then tue else 8.00) * !sal
let overPay = (if tue <= 8.00 then 0.00 else tue - 8.00) * overtimeSalary
(regTime, overTime, regPay, overPay)
member this.GetWednesdaySummary() =
let regTime = if wed <= 8.00 then wed else 8.00
let overTime = if wed <= 8.00 then 0.00 else wed - 8.00
let regPay = (if wed <= 8.00 then wed else 8.00) * !sal
let overPay = (if wed <= 8.00 then 0.00 else wed - 8.00) * overtimeSalary
(regTime, overTime, regPay, overPay)
member this.GetThursdaySummary()  = ((if thu <= 8.00 then thu else 8.00), (if thu <= 8.00 then 0.00 else thu - 8.00), ((if thu <= 8.00 then thu else 8.00) * !sal), ((if thu <= 8.00 then 0.00 else thu - 8.00) * overtimeSalary))
member this.GetFridaySummary()    = ((if fri <= 8.00 then fri else 8.00), (if fri <= 8.00 then 0.00 else fri - 8.00), ((if fri <= 8.00 then fri else 8.00) * !sal), ((if fri <= 8.00 then 0.00 else fri - 8.00) * overtimeSalary))
member this.GetSaturdaySummary()  = ((if sat <= 8.00 then sat else 8.00), (if sat <= 8.00 then 0.00 else sat - 8.00), ((if sat <= 8.00 then sat else 8.00) * !sal), ((if sat <= 8.00 then 0.00 else sat - 8.00) * overtimeSalary))
member this.GetSundaySummary()    = ((if sun <= 8.00 then sun else 8.00), (if sun <= 8.00 then 0.00 else sun - 8.00), ((if sun <= 8.00 then sun else 8.00) * !sal), ((if sun <= 8.00 then 0.00 else sun - 8.00) * overtimeSalary))

// Form: Time Sheet Pay Summary
let timeSheetPaySummary : Form = new Form(ClientSize = new Size(524, 338), MaximizeBox = false, Text = "Time Sheet and Pay Summary", StartPosition = FormStartPosition.CenterScreen)

timeSheetPaySummary.Controls.Add(new Label(Location = new Point(22, 24), AutoSize = true, Text = "Hourly Salary:"))
let txtHourlySalary : TextBox = new TextBox(Location = new Point(102, 21), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)

timeSheetPaySummary.Controls.Add(new Label(Location = new Point( 99, 57), AutoSize = true, Text = "Monday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(156, 57), AutoSize = true, Text = "Tuesday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(210, 57), AutoSize = true, Text = "Wednesday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(274, 57), AutoSize = true, Text = "Thursday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(329, 57), AutoSize = true, Text = "Friday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(386, 57), AutoSize = true, Text = "Saturday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(441, 57), AutoSize = true, Text = "Sunday"))

let txtTimeSheetMonday    : TextBox = new TextBox(Location = new Point(102, 76), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtTimeSheetTuesday   : TextBox = new TextBox(Location = new Point(159, 76), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtTimeSheetWednesday : TextBox = new TextBox(Location = new Point(216, 76), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtTimeSheetThursday  : TextBox = new TextBox(Location = new Point(273, 76), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtTimeSheetFriday    : TextBox = new TextBox(Location = new Point(330, 76), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtTimeSheetSaturday  : TextBox = new TextBox(Location = new Point(387, 76), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtTimeSheetSunday    : TextBox = new TextBox(Location = new Point(444, 76), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
timeSheetPaySummary.Controls.AddRange([| txtTimeSheetMonday; txtTimeSheetTuesday; txtTimeSheetWednesday; txtTimeSheetThursday; txtTimeSheetFriday; txtTimeSheetSaturday; txtTimeSheetSunday |])

let btnSummarize : Button = new Button(Location = new Point(27, 111), Size = new Size(468, 35), Text = "Summarize")

timeSheetPaySummary.Controls.Add(new Label(Location = new Point( 99, 159), AutoSize = true, Text = "Monday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(156, 159), AutoSize = true, Text = "Tuesday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(210, 159), AutoSize = true, Text = "Wednesday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(274, 159), AutoSize = true, Text = "Thursday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(329, 159), AutoSize = true, Text = "Friday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(386, 159), AutoSize = true, Text = "Saturday"))
timeSheetPaySummary.Controls.Add(new Label(Location = new Point(441, 159), AutoSize = true, Text = "Sunday"))

timeSheetPaySummary.Controls.Add(new Label(Location = new Point(23, 185), AutoSize = true, Text = "Regular Time:"))
let txtSummaryMonRegularTime : TextBox = new TextBox(Location = new Point(102, 182), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryTueRegularTime : TextBox = new TextBox(Location = new Point(159, 182), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryWedRegularTime : TextBox = new TextBox(Location = new Point(216, 182), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryThuRegularTime : TextBox = new TextBox(Location = new Point(273, 182), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryFriRegularTime : TextBox = new TextBox(Location = new Point(330, 182), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummarySatRegularTime : TextBox = new TextBox(Location = new Point(387, 182), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummarySunRegularTime : TextBox = new TextBox(Location = new Point(444, 182), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
timeSheetPaySummary.Controls.AddRange([| txtSummaryMonRegularTime; txtSummaryTueRegularTime; txtSummaryWedRegularTime; txtSummaryThuRegularTime; txtSummaryFriRegularTime; txtSummarySatRegularTime; txtSummarySunRegularTime |])

timeSheetPaySummary.Controls.Add(new Label(Location = new Point(23, 211), AutoSize = true, Text = "Overtime:"))
let txtSummaryMonOvertime : TextBox = new TextBox(Location = new Point(102, 208), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryTueOvertime : TextBox = new TextBox(Location = new Point(159, 208), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryWedOvertime : TextBox = new TextBox(Location = new Point(216, 208), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryThuOvertime : TextBox = new TextBox(Location = new Point(273, 208), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryFriOvertime : TextBox = new TextBox(Location = new Point(330, 208), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummarySatOvertime : TextBox = new TextBox(Location = new Point(387, 208), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummarySunOvertime : TextBox = new TextBox(Location = new Point(444, 208), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
timeSheetPaySummary.Controls.AddRange([| txtSummaryMonOvertime; txtSummaryTueOvertime; txtSummaryWedOvertime; txtSummaryThuOvertime; txtSummaryFriOvertime; txtSummarySatOvertime; txtSummarySunOvertime|])

timeSheetPaySummary.Controls.Add(new Label(Location = new Point(23, 237), AutoSize = true, Text = "Regular Pay:"))
let txtSummaryMonRegularPay : TextBox = new TextBox(Location = new Point(102, 234), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryTueRegularPay : TextBox = new TextBox(Location = new Point(159, 234), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryWedRegularPay : TextBox = new TextBox(Location = new Point(216, 234), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryThuRegularPay : TextBox = new TextBox(Location = new Point(273, 234), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryFriRegularPay : TextBox = new TextBox(Location = new Point(330, 234), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummarySatRegularPay : TextBox = new TextBox(Location = new Point(387, 234), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummarySunRegularPay : TextBox = new TextBox(Location = new Point(444, 234), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
timeSheetPaySummary.Controls.AddRange([| txtSummaryMonRegularPay; txtSummaryTueRegularPay; txtSummaryWedRegularPay; txtSummaryThuRegularPay; txtSummaryFriRegularPay; txtSummarySatRegularPay; txtSummarySunRegularPay |])

timeSheetPaySummary.Controls.Add(new Label(Location = new Point(23, 263), AutoSize = true, Text = "Overtime Pay:"))
let txtSummaryMonOvertimePay : TextBox = new TextBox(Location = new Point(102, 260), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryTueOvertimePay : TextBox = new TextBox(Location = new Point(159, 260), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryWedOvertimePay : TextBox = new TextBox(Location = new Point(216, 260), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryThuOvertimePay : TextBox = new TextBox(Location = new Point(273, 260), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummaryFriOvertimePay : TextBox = new TextBox(Location = new Point(330, 260), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummarySatOvertimePay : TextBox = new TextBox(Location = new Point(387, 260), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
let txtSummarySunOvertimePay : TextBox = new TextBox(Location = new Point(444, 260), Width = 51, Text = "0.00", TextAlign = HorizontalAlignment.Right)
timeSheetPaySummary.Controls.AddRange([| txtSummaryMonOvertimePay; txtSummaryTueOvertimePay; txtSummaryWedOvertimePay; txtSummaryThuOvertimePay; txtSummaryFriOvertimePay; txtSummarySatOvertimePay; txtSummarySunOvertimePay |])

let btnSummarizeClick e =
let hourlySalary = float txtHourlySalary.Text
let mon = float txtTimeSheetMonday.Text
let tue = float txtTimeSheetTuesday.Text
let wed = float txtTimeSheetWednesday.Text
let thu = float txtTimeSheetThursday.Text
let fri = float txtTimeSheetFriday.Text
let sat = float txtTimeSheetSaturday.Text
let sun = float txtTimeSheetSunday.Text

let ts = new TimeSheet(hourlySalary, mon, tue, wed, thu, fri, sat, sun)

let (monRegTime, monOvertime, monRegPay, monOvertiPay) = ts.GetMondaySummary()
let (tueRegTime, tueOvertime, tueRegPay, tueOvertiPay) = ts.GetTuesdaySummary()
let (wedRegTime, wedOvertime, wedRegPay, wedOvertiPay) = ts.GetWednesdaySummary()
let (thuRegTime, thuOvertime, thuRegPay, thuOvertiPay) = ts.GetThursdaySummary()
let (friRegTime, friOvertime, friRegPay, friOvertiPay) = ts.GetFridaySummary()
let (satRegTime, satOvertime, satRegPay, satOvertiPay) = ts.GetSaturdaySummary()
let (sunRegTime, sunOvertime, sunRegPay, sunOvertiPay) = ts.GetSundaySummary()

txtSummaryMonRegularTime.Text <- sprintf "%0.02f" monRegTime
txtSummaryMonOvertime.Text    <- sprintf "%0.02f" monOvertime
txtSummaryMonRegularPay.Text  <- sprintf "%0.02f" monRegPay
txtSummaryMonOvertimePay.Text <- sprintf "%0.02f" monOvertiPay

txtSummaryTueRegularTime.Text <- sprintf "%0.02f" tueRegTime
txtSummaryTueOvertime.Text    <- sprintf "%0.02f" tueOvertime
txtSummaryTueRegularPay.Text  <- sprintf "%0.02f" tueRegPay
txtSummaryTueOvertimePay.Text <- sprintf "%0.02f" tueOvertiPay

txtSummaryWedRegularTime.Text <- sprintf "%0.02f" wedRegTime
txtSummaryWedOvertime.Text    <- sprintf "%0.02f" wedOvertime
txtSummaryWedRegularPay.Text  <- sprintf "%0.02f" wedRegPay
txtSummaryWedOvertimePay.Text <- sprintf "%0.02f" wedOvertiPay

txtSummaryThuRegularTime.Text <- sprintf "%0.02f" thuRegTime
txtSummaryThuOvertime.Text    <- sprintf "%0.02f" thuOvertime
txtSummaryThuRegularPay.Text  <- sprintf "%0.02f" thuRegPay
txtSummaryThuOvertimePay.Text <- sprintf "%0.02f" thuOvertiPay

txtSummaryFriRegularTime.Text <- sprintf "%0.02f" friRegTime
txtSummaryFriOvertime.Text    <- sprintf "%0.02f" friOvertime
txtSummaryFriRegularPay.Text  <- sprintf "%0.02f" friRegPay
txtSummaryFriOvertimePay.Text <- sprintf "%0.02f" friOvertiPay

txtSummarySatRegularTime.Text <- sprintf "%0.02f" satRegTime
txtSummarySatOvertime.Text    <- sprintf "%0.02f" satOvertime
txtSummarySatRegularPay.Text  <- sprintf "%0.02f" satRegPay
txtSummarySatOvertimePay.Text <- sprintf "%0.02f" satOvertiPay

txtSummarySunRegularTime.Text <- sprintf "%0.02f" sunRegTime
txtSummarySunOvertime.Text    <- sprintf "%0.02f" sunOvertime
txtSummarySunRegularPay.Text  <- sprintf "%0.02f" sunRegPay
txtSummarySunOvertimePay.Text <- sprintf "%0.02f" sunOvertiPay

// Button: Close
let btnClose = new Button(Location = new System.Drawing.Point(420, 296), Text = "Close")
let btnCloseClick e = timeSheetPaySummary.Close()

do Application.Run timeSheetPaySummary```

Here is an example of executing the program:  Passing a Tuple to a Method

Just as seen with functions, an argument passed to a method can be treated as a tuple. When implementing the method, you can just pass a single value. In the body of the method, declare many variables and initialize them as one with the parameter. Then access the members of the tuple and use them any way you want. When calling the method, produce the appropriate number of members of the tuple.

Here is an example:

```open System
open System.Drawing
open System.Windows.Forms

type Employee(emplNbr, fName, lName, salary) =
member this.EmployeeNumber = emplNbr
member this.FirstName      = fName
member this.LastName       = lName
member this.YearlySalary   = salary

type Payroll(prNbr, emplNbr) =
let mutable pn : int = prNbr
let mutable en : string = emplNbr
member this.PayrollNumber  = prNbr
member this.EmployeeNumber = emplNbr

member this.CalculateTotalTime time =
let mon, tue, wed, thu, fri, sat, sun = time
mon + tue + wed + thu + fri + sat + sun

let empl = new Employee("92-840", "Martin", "Perhaps", 26.85)
let pay = new Payroll(10001, "92-840")

let totalTime = pay.CalculateTotalTime (8.00, 8.50, 10.00, 8.50, 9.50, 0.00, 0.00)

let payrollPreparation : Form = new Form()
payrollPreparation.MaximizeBox <- false
payrollPreparation.Text <- "Payroll Preparation"
payrollPreparation.ClientSize <- new System.Drawing.Size(264, 86)
payrollPreparation.StartPosition <- FormStartPosition.CenterScreen

// Label: Employee Number
let lblEmployeeNumber = new Label(AutoSize = true, Text = "Employee #:", Location = new Point(21, 18))

// Text Box: Employee Number
let txtEmployeeNumber = new TextBox(Location = new Point(101, 15), Size = new System.Drawing.Size(62, 20))

// Button: Find
let btnFind = new Button(Location = new Point(169, 13), Text = "Find Payroll", Width = 85)

// Label: Total Time Worked
let lblTotalTimeWorked = new Label(AutoSize = true, Text = "Time Worked:", Location = new Point(21, 53))

// Text Box: Total Time Worked
let txtTotalTimeWorked = new TextBox(Location = new Point(101, 50), Size = new System.Drawing.Size(62, 20))

let btnFindClick e =
if String.IsNullOrEmpty txtEmployeeNumber.Text <> true then
let emplNbr = txtEmployeeNumber.Text

if emplNbr = empl.EmployeeNumber then
txtTotalTimeWorked.Text <- sprintf "%0.02f" totalTime

[<EntryPoint>]
let main argv =
Application.Run payrollPreparation
0```

Here is an example of running the program: Remember that you can specify the number of members of the tuple parameter by specifying their types. Here is an example:

```type Payroll(prNbr, emplNbr) =
let mutable pn : int = prNbr
let mutable en : string = emplNbr
member this.PayrollNumber  = prNbr
member this.EmployeeNumber = emplNbr

member this.CalculateTotalTime (time : float * float * float * float * float * float * float) =
let mon, tue, wed, thu, fri, sat, sun = time
mon + tue + wed + thu + fri + sat + sun```
 Tuples and Properties

A property of a class can be created as a property. Normally, you can just create a property as member variable without specifying its data type. In the body of the class, to use the member as a tuple, you can declare a combination variable and initialize it with the combination with the tuple. You can then use each variable to access the members of the tuple. When creating an object from the class, provide the appropriate tuple as its values in the placeholder of the member. Here is an example:

```open System
open System.Drawing
open System.Windows.Forms

type Employee(emplNbr, fName, lName, salary) =
member this.EmployeeNumber = emplNbr
member this.FirstName      = fName
member this.LastName       = lName
member this.YearlySalary   = salary

type Payroll(prNbr, emplNbr, time) =
let mutable pn = prNbr
let mutable en = emplNbr
let mutable tm = time
member this.PayrollNumber  = prNbr
member this.EmployeeNumber = emplNbr
member this.TimeWorked     = time
member this.CalculateTotalTime() =
let mon, tue, wed, thu, fri, sat, sun = tm
mon + tue + wed + thu + fri + sat + sun

let empl = new Employee("92-840", "Martin", "Perhaps", 26.85)
let pay = new Payroll(10001, "92-840", (8.00, 8.50, 10.00, 8.50, 9.50, 0.00, 0.00))

let payrollPreparation : Form = new Form()
payrollPreparation.MaximizeBox <- false
payrollPreparation.Text <- "Payroll Preparation"
payrollPreparation.ClientSize <- new System.Drawing.Size(264, 86)
payrollPreparation.StartPosition <- FormStartPosition.CenterScreen

// Label: Employee Number
let lblEmployeeNumber = new Label(AutoSize = true, Text = "Employee #:", Location = new Point(21, 18))

// Text Box: Employee Number
let txtEmployeeNumber = new TextBox(Location = new Point(101, 15), Size = new System.Drawing.Size(62, 20))

// Button: Find
let btnFind = new Button(Location = new Point(169, 13), Text = "Find Payroll", Width = 85)

// Label: Total Time Worked
let lblTotalTimeWorked = new Label(AutoSize = true, Text = "Time Worked:", Location = new Point(21, 53))

// Text Box: Total Time Worked
let txtTotalTimeWorked = new TextBox(Location = new Point(101, 50), Size = new System.Drawing.Size(62, 20))

let btnFindClick e =
if String.IsNullOrEmpty txtEmployeeNumber.Text <> true then
let emplNbr = txtEmployeeNumber.Text

if emplNbr = empl.EmployeeNumber then
txtTotalTimeWorked.Text <- sprintf "%0.02f" (pay.CalculateTotalTime())

[<EntryPoint>]
let main argv =
Application.Run payrollPreparation
0```

When creating a property that is a tuple, if you want to indicate that it is a tuple, you can specify the types of its members. To do this, after the name of the mutable member, type a colon and the data type. Separate them with * from each other. Here is an example

```type Payroll(prNbr, emplNbr, time) =
let mutable pn : int = prNbr
let mutable en : string = emplNbr
let mutable tm : float * float * float * float * float * float * float = time
member this.PayrollNumber  = prNbr
member this.EmployeeNumber = emplNbr
member this.TimeWorked     = time
member this.CalculateTotalTime() =
let mon, tue, wed, thu, fri, sat, sun = tm
mon + tue + wed + thu + fri + sat + sun```

In the same way, you can specify the types of the members of the tuple wherever it is supposed to be used. Here are examples:

```type Payroll(prNbr, emplNbr, time : float * float * float * float * float * float * float) =
let mutable pn : int = prNbr
let mutable en : string = emplNbr
let mutable tm : float * float * float * float * float * float * float = time
member this.PayrollNumber  = prNbr
member this.EmployeeNumber = emplNbr
member this.TimeWorked     : float * float * float * float * float * float * float = time
member this.CalculateTotalTime() =
let mon, tue, wed, thu, fri, sat, sun = tm
mon + tue + wed + thu + fri + sat + sun```
 Passing a Tuple to a Constructor

At this time, you may have found that a constructor doesn't take parameters in a curried form like normal functions or methods do. The parameters passed to a constructor are provided as a tuple. Consider the following constructor:

```type Customer(actNbr, name, emrg) =
let mutable nbr = actNbr
let mutable name = name
let mutable emergency = emrg
member this.AccountNumber with get() = nbr and set(value) = nbr <- value
member this.FullName with get() = name and set(value) = name <- value
member this.EmergencyInformation with get() = emergency and set(value) = emergency <- value```

Because F# is an inferred language, if you don't specify the type of a parameter, the construtor (or method) may not know the type of value of the parameter until the constructor (oe the method) is called. You can use this feature to pass a tuple to a constructor when creating an object. Here is an example:

`let client = Customer("9614-9203", ("James", 'D', "Watts"), ("Frank Watts", "(301) 402-6084"))`

If you need to access each member of a tuple, remember that you can use a matching tuple.

 Tuples and Named Arguments

When you call a method that takes a tuple, you must provide the values of the tuple in the appropriate order. F# allows you to provide the values in the order of your choice. To do this, when calling the method, in the parentheses, type each parameter name followed by = and its value. Here is an example:

```type HotelRoom(number, roomType, rate) =
member this.RoomNumber = number
member this.RoomType = roomType
member this.DailyRate = rate
member this.CalculateInvoice(days, phoneCharge, discount) =
(float days * rate) + phoneCharge - (float days * rate * discount / 100.00)

let room = HotelRoom(104, "Conference Room", 450.00)
let days = 3
let phoneUse = 12.48
let total = room.CalculateInvoice(phoneCharge = 12.48, days = 3, discount = 20.00)```

By default, you should use unique names for methods in a class. If you try creating two methods with the same name and the exact same signature (in the same class), you would receive an error. Fortunately, there is an alternative. You can provide different versions of the same method in a class. This is referred to as method overloading.

Method overloading consists of having various signatures for the same method. This means that different methods can have the same name but different formats of parameters. One of the methods can be in curreid form and the other(s) take (a) tuple(s). This means that one version can be created like a function that takes parameters separated by spaces. The other versions can each take one or more tuples. Here are examples:

```type HotelRoom(number, roomType, rate) =
member this.RoomNumber = number
member this.RoomType = roomType
member this.DailyRate = rate

member this.CalculateInvoice days = float days * rate // Curried Form
member this.CalculateInvoice (days, phoneCharge) =    // Tuple Form: A pair
(float days * rate) + phoneCharge
member this.CalculateInvoice (days, phoneCharge, discountRate) = // Tuple Form
(float days * rate) + phoneCharge - (float days * rate * discountRate / 100.00)

let room110 = HotelRoom(roomType = "Conference Room", rate = 450.00, number = 110)
let mutable days, phoneUse = 1, 0.00
// Calling the version with curried form
let mutable total = room110.CalculateInvoice days

let room102 = HotelRoom(roomType = "Bedroom", rate = 95.50, number = 102)
days <- 5
phoneUse <- 7.46
// Calling the version with a paired tuple form
total <- room102.CalculateInvoice(days, phoneUse)

let room212 = HotelRoom(rate = 95.50, number = 212, roomType = "Bedroom")
days <- 3
phoneUse <- 15.68
// Calling the version with tuple form
total <- room212.CalculateInvoice(days, phoneUse, 20.00)```
 A Tuple in a Tuple

Each member of a tuple is a placeholder for any type. This means that each element (or the placeholder of an element) can be its own tuple. This allows you to create a tuple in another tuple or to create tuples in a tuple. When doing this, remember that each tuple must use its own parentheses. Here an example of a tuple that contains other tuples:

`("529-385", ("Peter", "James", "Watson"), ("Julie watson", "240-144-0285"))`

Remember that you can write tuple members on separate lines to make the code easy to read. Here is an example:

```(529385,
("Peter", "Josh", "Watson"),
("Julie watson", "240-144-0285")
);```

As defined in the variable, the primary tuple contains three members. For our example, the first member is an account number and we used one value for it. The second member represents a name; we defined it as a tuple with three members. Our last member represents emergency contact information. We represent it as a tuple with two members (an emergency name and an emergency phone number).

Of course, each tuple can use different types of values.