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 are,
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.

This also means that a tuple is not a simple type like a primitive (int, bool, float, etc). The
reason is that, although a tuple is treated as a tuple, it is internally made of
distinguishable values. The values can be numbers,
characters, strings, objects (from classes), etc. The members of the tuple can also consist of expressions,
etc. The items, or members, 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:

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 two items, it is called a pair. Here is an example:

("Frank", "James")

If a tuple is made of three members, it is called a tripple

If a tuple is made of four members, it can be called a quadruple

If a tuple is made of five members, it can be called a quintuple

If a tuple is made of six members, it is called a sextuple

If a tuple is made of seven members, it is called a septuple

If a tuple is made of eight members, it is called an octuple

The Types of Members of a Tuple

The tuple is the most fundamental collection of F# and we will see other means of creating collections in F#. Most collection types in F# must have the same type of value. The tuple type doesn't follow that rule. Each member of a tuple can be a type different from the other members. Here is an example:

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

In this case, we create a tuple of 5 elements. 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 in the first lesson, F# is an inferred language:
the compiler is able to figure the type of a variable based on the value you
assign to it. This also applies to tuples. When you create a tuple, once you
specify its members, the compiler applies the appropriate type to each member.
Still, if you want, you can indicate the data type of each member. 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 items are of different types, enter the appropriate
type of a member in the corresponding placeholder. Here is an example:

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 items 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 Members of a Tuple

Binding a tuple consists of specifying names of its
members and 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 item will have the first value
of the tuple; the second named item will have the second value of the tuple, and
so on. Here is an example:

Eventually, in your code, you will be able to refer to an
item using its name. If you are not planning to refer to a certain member, 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:

A tuple is primarily a list. The primary way you can use it
consists of displaying its values to the user. To do this from the printf or the printfn()
function, use the %A placeholder. Here is an example:

printfn "%A" ( 1, 4, 6, 12, 36 );

This would produce:

(1, 4, 6, 12, 36)
Press any key to continue . . .

If the tuple is stored in a variable, use the same %A in the printf or
the printfn() function and pass the name of the variable as
the second argument. This can be done as follows:

let numbers = (1, 4, 6, 12, 36);
printfn "%A" numbers;

Accessing the Members 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 using the value in its
corresponding position in the tuple. Here are examples:

The result of 2 < 7 is true
The result of 15 < 8 is false
Press any key to continue . . .

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 <<<, >>>, ^^^.

Passing a Tuple as Parameter

Remember that 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. Here is an example:

let show (a, b, c, d)

This format is referrred to as tuple form.

After doing this, you can use the tuple or its members in the body of
the function. For example, you can use the function to display the values
of the individual members of the tuple. Here is an example:

In the same way, you can pass a combination of (a) tuple(s) and (an)other type(s).
Consider the following example:

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

In this case, you can creating a function that is receiving
two tuples (one pair and one triple) and one argument of any kind. In reality,
when creating a function that takes many arguments, each argument is simply
positioned in a placeholder, and each argument can be anything. This means that
an argument that is represented with one word can as well be an argument.
Consider the following example:

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

Any one of these arguments can be treated as an argument 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 an argument 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:

When creating the functions, if you want to indicate that an
argument 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:

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 wants, 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:

If you create such a tuple where you don't name the members and simply assign it to a variable, there is no tuple built-in operator to access each member. A solution is use patter matching. To use it, create a matching pattern with one case. The case must be created as a tuple and 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:

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.

Returning a Value Off a Tuple

A tuple is primarily a value like any other in functional
programming. When a tuple is passed to as argument, the function can use the
tuple or its items as it sees fit. For example, the function can perform
operations on the members of the tuple. Here is an example that takes a tuple as
argument, multiplies the members of that tuple and returns the result as a
constant value:

The sine, the cosine, and the tangent of 45 are: (0.8509035245, 0.5253219888, 1.619775191)
Press any key to continue . . .

Of course, a function can receive any number of arguments and
return any type of tuple. To consider an example, imagine you want to solve a
system of equations in the form:

a1x + b1y = c1
a2x + b2y = c2

Of course, if we know anything about mathematics, it is that
there is not a single way to solve such a problem. There are always various ways. For our example, we
can solve the
first equation by x. That gives us:

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:

Notice that the result is given in one combination. 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. Here is an example:

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:

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:

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:

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:

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:

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:

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:

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:

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).