﻿ F# Collections: A Set as a Collection of Elements
 F# Collections: A Set of Elements

 Fundamentals of a Set

 Introduction
 A set is a collection of items called elements. The elements can be of any kind: numbers (naturals or decimals), strings (words, names, titles, sentences, etc), or objects (from classes).

In algebra, a set is usually represented with an uppercase letter, such as A, R, or W.

 Creating a Set

To support sets, the F# language provides a module named Set. This module is included in the Microsoft.FSharp.Collections namespace.

To create a set in F#, you can use the set keyword. It is followed by []. Inside of them, create your list of elements. You have various options. The most fundamental or the easiest way to create a set is to create a list of values between [ and ] and separate them with semicolons. Here is an example:

`set [ 2; 37; 4; 3774; 38; 74; 31 ]`

As done for lists and arrays, each item can be written on its own line.

The values of a set can be of any kind, including a structure, a class, or a record. Here is an example that uses a record:

```type ZoneInclusion = | Entirely | Split

type State = {
Name      : string
Inclusion : ZoneInclusion }

set [ { Name = "Maine"; Inclusion = Entirely }; { Name = "Michigan"; Inclusion = Split } ]```

Instead of semicolons, you can separate the elements with commas. Here is an example:

`set [ 20, 8, 93, 405, 3, 40 ]`

If you do this, all of the items are considered as belonging to one (or a common) tuple. This means that the elements would be treated as a group.

If you want to use the set over and over again, declare a variable and initialize it with the set. Here is a example:

`let series = set [ 20; 8; 93; 405; 8; 3; 40 ]`
 Accessing a Set

Because a set is primarily a list, it and its elements are accessed as done for a List. To access all elements as one, you can use the %A operator in the desired placeholder. Here is an example:

```let names = set [ "Kevin"; "Jane"; "Daniel"; "Ruth"; "Paul" ]

lblNames.Text <- "Names: %A" names```

To access each element of the set, you can use a for...in. Here is an example:

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

let evaluations = set [ "True Positive"; "True Negative"; "False Positive"; "False Negative" ]

let classification = new Form(MaximizeBox = false, StartPosition = FormStartPosition.CenterScreen,
Text = "Classification", ClientSize = new System.Drawing.Size(175, 92))

let lbxClassifications = new ListBox(Size = new System.Drawing.Size(150, 65), Location = new Point(12, 17))

let mutable i = 0

for evaluation in evaluations do

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

This would produce:

You can use the same technique if the elements are from a class or a record. Other than that, the Set module contains most of the same functions as the List module, allowing you to perform all types of operations.

 Characteristics of a Set

 An Empty Set

An empty set is one that doesn't contain any element. In algebra, an empty set is represented with the uppercase phi letter. The lette can be assigned to an uppercase letter. Here is an example:

`A = ∅`

In algebra, to visually represent a set, we draw an empty or blank circle:

To create an empty set, declare a variable and assign the empty property of the Set class to it. Here is an example:

`let something = Set.empty`

To let you find out whether a set is empty, the Set module provides a function named isEmpty. Its signature is:

`Set.isEmpty : Set<'T> -> bool`

Here is an example of calling this function:

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

let evaluations = set [ "True Positive"; "True Negative"; "False Positive"; "False Negative" ]

let classification = new Form(MaximizeBox = false, StartPosition = FormStartPosition.CenterScreen,
Text = "Classification", ClientSize = new System.Drawing.Size(175, 92))

let lbxClassifications = new ListBox(Size = new System.Drawing.Size(150, 65), Location = new Point(12, 17))

let mutable i = 0

if Set.isEmpty evaluations then
MessageBox.Show("The set doesn't contain any element", "Classification",
MessageBoxButtons.OK, MessageBoxIcon.Information) |> ignore
else
for evaluation in evaluations do

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

As an alternative, the Set class is equipped with a function named IsEmpty. Its signature is:

`member this.IsEmpty :  bool`
 The Number of Elements in a Set

The number of elements in a set is referred to as its length or count. A set is said to be finite if it contains a fixed number of elements. An infinite set is one whose count is not fixed. To let you get the number of elements of a set, the Set module provides a property named count. Here is an example:

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

type ZoneInclusion = | Entirely | Split

type State = {
Name : string
Inclusion : ZoneInclusion }

let eastern = set [ { Name = "Maine";           Inclusion = Entirely }
{ Name = "Vermont";         Inclusion = Entirely }
{ Name = "New Hampshire";   Inclusion = Entirely }
{ Name = "Massachusetts";   Inclusion = Entirely }
{ Name = "Rhode Island";    Inclusion = Entirely }
{ Name = "Connecticut";     Inclusion = Entirely }
{ Name = "Michigan";        Inclusion = Split    }
{ Name = "New York";        Inclusion = Entirely }
{ Name = "New Jersey";      Inclusion = Entirely }
{ Name = "Indiana";         Inclusion = Split    }
{ Name = "Ohio";            Inclusion = Entirely }
{ Name = "Pennsylvania";    Inclusion = Entirely }
{ Name = "Delaware";        Inclusion = Entirely }
{ Name = "Maryland";        Inclusion = Entirely }
{ Name = "Washington D.C."; Inclusion = Entirely }
{ Name = "West Virginia";   Inclusion = Entirely }
{ Name = "Kentucky";        Inclusion = Split    }
{ Name = "Virginia";        Inclusion = Entirely }
{ Name = "Tennessee";       Inclusion = Split    }
{ Name = "North Carolina";  Inclusion = Entirely }
{ Name = "South Carolina";  Inclusion = Entirely }
{ Name = "Georgia";         Inclusion = Entirely }
{ Name = "Alabama";         Inclusion = Split    }
{ Name = "Florida";         Inclusion = Split    } ]

let count = Set.count eastern

let timeManagement = new Form(MaximizeBox = false, Text = "Time Management",
ClientSize = new System.Drawing.Size(325, 55),
StartPosition = FormStartPosition.CenterScreen)

let lblNumberOfStates = new Label(AutoSize = true, Location = new Point(14, 17),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Bottom))

lblNumberOfStates.Text <- "Number of US states involved with Eastern Time Zone: " + sprintf "%d" count

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

This would produce:

As an alternative, the Set class is equipped with a property named Count. Here is an example of accessing it:

```let names = set [ "Kevin"; "Jane"; "Daniel"; "James"; "Ruth"; "Paul" ]

sprintf "The set contains %i elements" names.Count```
 A Set is Automatically Sorted

After a set has been created, every time before it is used, the compiler first internally sorts the elements of the set, based on their type. If the set is made of numbers, they are sorted in incrementing order. Here is an example:

`let series = set [ 20; 8; 93; 405; 8; 3; 40 ]`

This would produce:

`set [3; 8; 20; 40; 93; 405]`

If the members of the set are strings, the set gets sorted in alphabetical order. Here is an example we saw earlier:

`let names = set [ "Kevin"; "Jane"; "Daniel"; "Ruth"; "Paul" ]`

This would produce:

`set [ Daniel; Jane; Kevin; Paul; Ruth ]`

If the set is made of dates, they are sorted in chronological order. Here is an example:

 No Duplicate Value in a Set

A set should (must) not have a duplicate element. If you add duplicate values to a set, the compiler would internally remove every duplicate element. Consider the following example:

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

let names = set [ "Kevin";
"Jane";
"Daniel";
"James";
"Ruth";
"Jane";
"Paul";
"James" ]

let employment = new Form(MaximizeBox = false, StartPosition = FormStartPosition.CenterScreen,
Text = "Employment", ClientSize = new System.Drawing.Size(175, 115))

let lbxEmployees  : ListBox = new ListBox(Size = new System.Drawing.Size(150, 85), Location = new Point(12, 17))

let mutable i = 0

for name in names do

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

Notice that some elements are repeated. This program would produce:

Notice that the end result doesn't contain duplicates.

 The Lowest Value of a Set

As mentioned already, after a set has been created but before it is used, the compiler internally rearranges the elements. As a result, the element that was first added may loose its posibion. To let you find out what element is currently the lowest, the Set class is equipped with a property named MinimumElement. Here is an example of a set:

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

type ZoneInclusion = | Entirely | Split

type State = {
Name : string
Inclusion : ZoneInclusion }

let eastern = set [ { Name = "Maine";           Inclusion = Entirely }
{ Name = "Vermont";         Inclusion = Entirely }
{ Name = "New Hampshire";   Inclusion = Entirely }
{ Name = "Massachusetts";   Inclusion = Entirely }
{ Name = "Rhode Island";    Inclusion = Entirely }
{ Name = "Connecticut";     Inclusion = Entirely }
{ Name = "Michigan";        Inclusion = Split    }
{ Name = "New York";        Inclusion = Entirely }
{ Name = "New Jersey";      Inclusion = Entirely }
{ Name = "Indiana";         Inclusion = Split    }
{ Name = "Ohio";            Inclusion = Entirely }
{ Name = "Pennsylvania";    Inclusion = Entirely }
{ Name = "Delaware";        Inclusion = Entirely }
{ Name = "Maryland";        Inclusion = Entirely }
{ Name = "Washington D.C."; Inclusion = Entirely }
{ Name = "West Virginia";   Inclusion = Entirely }
{ Name = "Kentucky";        Inclusion = Split    }
{ Name = "Virginia";        Inclusion = Entirely }
{ Name = "Tennessee";       Inclusion = Split    }
{ Name = "North Carolina";  Inclusion = Entirely }
{ Name = "South Carolina";  Inclusion = Entirely }
{ Name = "Georgia";         Inclusion = Entirely }
{ Name = "Alabama";         Inclusion = Split    }
{ Name = "Florida";         Inclusion = Split    } ]

let first = eastern.MinimumElement

let timeManagement = new Form(MaximizeBox = false, Text = "Time Management",
ClientSize = new System.Drawing.Size(325, 55),
StartPosition = FormStartPosition.CenterScreen)

let lblState = new Label(AutoSize = true, Location = new Point(14, 17),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Bottom))

lblState.Text <- "First state in alphabetical order: " + first.Name

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

This would produce:

Alternatively, the Set module provides a member variable named minElement. Here is an example of accessing it:

```let lunchSpecial = set [ "Sweet and Sour Chicken";
"Cashew Chicken";
"Kung Pao Chicken";
"Szechuan Chicken";
"Hunan Chicken"; ]

let first = Set.minElement lunchSpecial

sprintf "The first food item is named %s" first```

This would produce:

```set [ "Cashew Chicken"
"Hunan Chicken"
"Kung Pao Chicken"
"Sweet and Sour Chicken"
"Szechuan Chicken" ]

The first food item is named Cashew Chicken```
 The Highest Element in a Set

To let you get the highest element in a set, the Set class is equipped with a property named MaximumElement. Here is an example of accessing it:

```let numbers = set [ 10; 830; 4; 80; 38482; 2; 30; 48 ]

let highest = numbers.MaximumElement

sprintf "The highest number of the set is %i" highest```

This would produce:

```set [ 2; 4; 10; 30; 48; 80; 830; 38482 ]

The highest number of the set is 38482```

As an alternatively, the Set module provides a member named maxElement. Here is an example of using it:

```let lunchSpecial = set [ "Sweet and Sour Chicken";
"Cashew Chicken";
"Kung Pao Chicken";
"Szechuan Chicken";
"Hunan Chicken"; ]

let last = Set.maxElement lunchSpecial

sprintf "The last food item is named %s" last```

This would produce:

```set [ "Cashew Chicken"
"Hunan Chicken"
"Kung Pao Chicken"
"Sweet and Sour Chicken"
"Szechuan Chicken" ]

The last food item is named Szechuan Chicken```
 Fundamental Operations on a Set

 A Singleton

A singleton is a set that contains only one element. To let you create a singleton, the Set module provides the singleton function. Its signature is:

`Set.singleton : 'T -> Set<'T>`

Here is an example:

```let nbr = Set.singleton 248

sprintf "Number: %A" nbr```

This wold produce:

`Number: set [248]`
 Iterating Through a Set

To let you iterate through the elements of a set, the Set module provides a functions named iter. Its signature is:

`Set.iter : ('T -> unit) -> Set<'T> -> unit `

This function takes two arguments. The first is a function to use on each element. The second argument is a list. Here is an example:

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

type ZoneInclusion = | Entirely | Split

type State = {
Name : string
Inclusion : ZoneInclusion }

let eastern = set [ { Name = "Maine";           Inclusion = Entirely }
{ Name = "Vermont";         Inclusion = Entirely }
{ Name = "New Hampshire";   Inclusion = Entirely }
{ Name = "Massachusetts";   Inclusion = Entirely }
{ Name = "Rhode Island";    Inclusion = Entirely }
{ Name = "Connecticut";     Inclusion = Entirely }
{ Name = "Michigan";        Inclusion = Split    }
{ Name = "New York";        Inclusion = Entirely }
{ Name = "New Jersey";      Inclusion = Entirely }
{ Name = "Indiana";         Inclusion = Split    }
{ Name = "Ohio";            Inclusion = Entirely }
{ Name = "Pennsylvania";    Inclusion = Entirely }
{ Name = "Delaware";        Inclusion = Entirely }
{ Name = "Maryland";        Inclusion = Entirely }
{ Name = "Washington D.C."; Inclusion = Entirely }
{ Name = "West Virginia";   Inclusion = Entirely }
{ Name = "Kentucky";        Inclusion = Split    }
{ Name = "Virginia";        Inclusion = Entirely }
{ Name = "Tennessee";       Inclusion = Split    }
{ Name = "North Carolina";  Inclusion = Entirely }
{ Name = "South Carolina";  Inclusion = Entirely }
{ Name = "Georgia";         Inclusion = Entirely }
{ Name = "Alabama";         Inclusion = Split    }
{ Name = "Florida";         Inclusion = Split    } ]

let count = Set.count eastern

let timeManagement = new Form(MaximizeBox = false, Text = "Time Management",
ClientSize = new System.Drawing.Size(250, 210),
StartPosition = FormStartPosition.CenterScreen)

let lvwTimeZones = new ListView(GridLines = true, View = View.Details,
Size = new System.Drawing.Size(225, 144),
FullRowSelect = true, Location = new Point(12, 12),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Top ||| AnchorStyles.Right ||| AnchorStyles.Bottom))

let mutable col = lvwTimeZones.Columns.Add("State", 140)

let lblNumberOfStates = new Label(Size = new System.Drawing.Size(225, 42), Location = new Point(14, 170),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Bottom))

Set.iter (fun timeZone ->
let mutable lviTimeZone = new ListViewItem()
lviTimeZone.Text <- (sprintf "%s" timeZone.Name)
lviTimeZone.SubItems.Add (sprintf "%A" timeZone.Inclusion) |> ignore

lblNumberOfStates.Text <- "Number of states entirely or partially involved with Eastern Time Zone: " + sprintf "%d" count

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

As an alternative, you can apply the set to the function call. Here is an example:

```eastern |> Set.iter (fun timeZone ->
let mutable lviTimeZone = new ListViewItem()
lviTimeZone.Text <- (sprintf "%s" timeZone.Name)
lviTimeZone.SubItems.Add (sprintf "%A" timeZone.Inclusion) |> ignore

This would produce:

 Adding an Element to a Set

As you may know already, collections in F# are immutable; meaning that once you create a set, you cannot add new elements to it. Instead, you can create a new set that contains elements from an existing set and other elements. To let you perform this operation, the Set class is equipped with a method named Add. Its signature is:

`member this.Add : 'T -> Set<'T>`

This method takes one argument as the item to be added to the set that called it. Here are two examples:

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

type ChemicalElement = {
AtomicNumber : int
Name         : string
Symbol       : string
AtomicMass   : string }

let periodicTable = set [ { Name = "Hydrogen"; Symbol = "H";  AtomicNumber =  1; AtomicMass = "1.0079"  }
{ Name = "Helium";   Symbol = "He"; AtomicNumber =  2; AtomicMass = "4.0026"  }
{ Name = "Lithium";  Symbol = "Li"; AtomicNumber =  3; AtomicMass = "6.941"   }
{ Name = "Berylium"; Symbol = "Be"; AtomicNumber =  4; AtomicMass = "9.0122"  }
{ Name = "Boron";    Symbol = "B";  AtomicNumber =  5; AtomicMass = "10.811"  }
{ Name = "Carbon";   Symbol = "C";  AtomicNumber =  6; AtomicMass = "12.011"  }
{ Name = "Nitrogen"; Symbol = "N";  AtomicNumber =  7; AtomicMass = "14.0067" }
{ Name = "Oxygen";   Symbol = "O";  AtomicNumber =  8; AtomicMass = "15.9994" }
{ Name = "Fluorine"; Symbol = "F";  AtomicNumber =  9; AtomicMass = "18.9984" }
{ Name = "Neon";     Symbol = "Ne"; AtomicNumber = 10; AtomicMass = "20.1797" } ]

let withSodium = periodicTable.Add { AtomicNumber =  11; Name = "Sodium"; Symbol = "Na";  AtomicMass = "22.9898" }
let withMagnesium = withSodium.Add { AtomicNumber =  12; Name = "Magnesium"; Symbol = "Mg";  AtomicMass = "24.3050" }

let chemistry = new Form(MaximizeBox = false, Text = "Periodic Table",
ClientSize = new System.Drawing.Size(330, 192),
StartPosition = FormStartPosition.CenterScreen)

let lvwElements = new ListView(GridLines = true, View = View.Details,
Size = new System.Drawing.Size(303, 166),
FullRowSelect = true, Location = new Point(12, 12))

let mutable col = lvwElements.Columns.Add("Atomic Number", 85)
col <- lvwElements.Columns.Add("Atomic Mass", 75, HorizontalAlignment.Right)

Set.iter (fun (element : ChemicalElement) ->
let mutable lviElement = new ListViewItem()
lviElement.Text <- (sprintf "%i" element.AtomicNumber)
lviElement.SubItems.Add (sprintf "%s" element.Name) |> ignore
lviElement.SubItems.Add (sprintf "%s" element.Symbol) |> ignore
lviElement.SubItems.Add (sprintf "%s" element.AtomicMass) |> ignore

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

This would produce:

Because the Set.Add() method returns a set, you can keep calling it to add as many elements as you want. Here is an example that calls it three times to add some elements:

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

type ChemicalElement = {
AtomicNumber : int
Name         : string
Symbol       : string
AtomicMass   : string }

let periodicTable = set [ { Name = "Hydrogen"; Symbol = "H";  AtomicNumber =  1; AtomicMass = "1.0079"  }
{ Name = "Helium";   Symbol = "He"; AtomicNumber =  2; AtomicMass = "4.0026"  }
{ Name = "Lithium";  Symbol = "Li"; AtomicNumber =  3; AtomicMass = "6.941"   }
{ Name = "Berylium"; Symbol = "Be"; AtomicNumber =  4; AtomicMass = "9.0122"  }
{ Name = "Boron";    Symbol = "B";  AtomicNumber =  5; AtomicMass = "10.811"  }
{ Name = "Carbon";   Symbol = "C";  AtomicNumber =  6; AtomicMass = "12.011"  }
{ Name = "Nitrogen"; Symbol = "N";  AtomicNumber =  7; AtomicMass = "14.0067" }
{ Name = "Oxygen";   Symbol = "O";  AtomicNumber =  8; AtomicMass = "15.9994" }
{ Name = "Fluorine"; Symbol = "F";  AtomicNumber =  9; AtomicMass = "18.9984" }
{ Name = "Neon";     Symbol = "Ne"; AtomicNumber = 10; AtomicMass = "20.1797" } ]

let withSodium = periodicTable.Add { AtomicNumber =  11; Name = "Sodium"; Symbol = "Na";  AtomicMass = "22.9898" }
let withMagnesium = withSodium.Add { AtomicNumber =  12; Name = "Magnesium"; Symbol = "Mg";  AtomicMass = "24.3050" }

let elements = (((((withMagnesium.Add { Name = "Aluminium"; AtomicNumber =  13; Symbol = "Al";  AtomicMass = "26.9815" })
.Add { Name = "Silicon";    AtomicNumber =  14; Symbol = "Si"; AtomicMass = "28.0855" })
.Add { Name = "Phosphorus"; AtomicNumber =  15; Symbol = "P";  AtomicMass = "30.9738" })
.Add { Name = "Sulfur";     AtomicNumber =  16; Symbol = "S";  AtomicMass = "32.066"  })
.Add { Name = "Chlorine";   AtomicNumber =  17; Symbol = "Cl"; AtomicMass = "35.4527" })
.Add { Name = "Argon";     AtomicNumber =  18; Symbol = "Ar"; AtomicMass = "39.948"  }

let chemistry = new Form(MaximizeBox = false, Text = "Periodic Table",
ClientSize = new System.Drawing.Size(330, 192),
StartPosition = FormStartPosition.CenterScreen)

let lvwElements = new ListView(GridLines = true, View = View.Details,
Size = new System.Drawing.Size(303, 166),
FullRowSelect = true, Location = new Point(12, 12))

let mutable col = lvwElements.Columns.Add("Atomic Number", 85)
col <- lvwElements.Columns.Add("Atomic Mass", 75, HorizontalAlignment.Right)

Set.iter (fun (element : ChemicalElement) ->
let mutable lviElement = new ListViewItem()
lviElement.Text <- (sprintf "%i" element.AtomicNumber)
lviElement.SubItems.Add (sprintf "%s" element.Name) |> ignore
lviElement.SubItems.Add (sprintf "%s" element.Symbol) |> ignore
lviElement.SubItems.Add (sprintf "%s" element.AtomicMass) |> ignore

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

This would produce:

To support this operation, the Set module provides a function named add. Its signature is:

`Set.add : 'T -> Set<'T> -> Set<'T>`

This function takes two arguments. The first is the element to add to the second argument which is a set. The function returns a set. You can call the function once to add an item. In the same way, you can keep calling the Set.add() function to add as many elements as you want.

 A Mutable Set

A mentioned already, when a set is created, it number of elements is fixed, which means that you cannot add new elements to it, except if you want to create a new set. An alternative is to make the set mutable. This would allow you to add items to a set that already holds one or more elements. Here is an example:

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

type ChemicalElement = {
AtomicNumber : int
Name         : string
Symbol       : string
AtomicMass   : string }

let periodicTable = set [ { Name = "Hydrogen"; Symbol = "H";  AtomicNumber =  1; AtomicMass = "1.0079"  }
{ Name = "Helium";   Symbol = "He"; AtomicNumber =  2; AtomicMass = "4.0026"  }
{ Name = "Lithium";  Symbol = "Li"; AtomicNumber =  3; AtomicMass = "6.941"   }
{ Name = "Berylium"; Symbol = "Be"; AtomicNumber =  4; AtomicMass = "9.0122"  }
{ Name = "Boron";    Symbol = "B";  AtomicNumber =  5; AtomicMass = "10.811"  }
{ Name = "Carbon";   Symbol = "C";  AtomicNumber =  6; AtomicMass = "12.011"  }
{ Name = "Nitrogen"; Symbol = "N";  AtomicNumber =  7; AtomicMass = "14.0067" }
{ Name = "Oxygen";   Symbol = "O";  AtomicNumber =  8; AtomicMass = "15.9994" }
{ Name = "Fluorine"; Symbol = "F";  AtomicNumber =  9; AtomicMass = "18.9984" }
{ Name = "Neon";     Symbol = "Ne"; AtomicNumber = 10; AtomicMass = "20.1797" } ]

let withSodium = periodicTable.Add { AtomicNumber =  11; Name = "Sodium"; Symbol = "Na";  AtomicMass = "22.9898" }
let withMagnesium = withSodium.Add { AtomicNumber =  12; Name = "Magnesium"; Symbol = "Mg";  AtomicMass = "24.3050" }

let elements = (((((withMagnesium.Add { Name = "Aluminium"; AtomicNumber =  13; Symbol = "Al";  AtomicMass = "26.9815" })
.Add { Name = "Silicon";    AtomicNumber =  14; Symbol = "Si"; AtomicMass = "28.0855" })
.Add { Name = "Phosphorus"; AtomicNumber =  15; Symbol = "P";  AtomicMass = "30.9738" })
.Add { Name = "Sulfur";     AtomicNumber =  16; Symbol = "S";  AtomicMass = "32.066"  })
.Add { Name = "Chlorine";   AtomicNumber =  17; Symbol = "Cl"; AtomicMass = "35.4527" })
.Add { Name = "Argon";     AtomicNumber =  18; Symbol = "Ar"; AtomicMass = "39.948"  }

let mutable chemicalTable = elements.Add { AtomicNumber =  19; Name = "Potassium"; Symbol = "K";  AtomicMass = "39.0983" }
chemicalTable <- chemicalTable.Add { AtomicNumber =  19; Name = "Potassium"; Symbol = "K";  AtomicMass = "39.0983" }
chemicalTable <- chemicalTable.Add { AtomicNumber =  20; Name = "Calcium";   Symbol = "Ca"; AtomicMass = "40.078"  }
chemicalTable <- chemicalTable.Add { AtomicNumber =  21; Name = "Scandium";  Symbol = "Sc"; AtomicMass = "44.9559" }
chemicalTable <- chemicalTable.Add { AtomicNumber =  22; Name = "Titanium";  Symbol = "Ti"; AtomicMass = "47.88"   }

let chemistry = new Form(MaximizeBox = false, Text = "Periodic Table",
ClientSize = new System.Drawing.Size(330, 192),
StartPosition = FormStartPosition.CenterScreen)

let lvwElements = new ListView(GridLines = true, View = View.Details,
Size = new System.Drawing.Size(303, 166),
FullRowSelect = true, Location = new Point(12, 12))

let mutable col = lvwElements.Columns.Add("Atomic Number", 85)
col <- lvwElements.Columns.Add("Atomic Mass", 75, HorizontalAlignment.Right)

Set.iter (fun (element : ChemicalElement) ->
let mutable lviElement = new ListViewItem()
lviElement.Text <- (sprintf "%i" element.AtomicNumber)
lviElement.SubItems.Add (sprintf "%s" element.Name) |> ignore
lviElement.SubItems.Add (sprintf "%s" element.Symbol) |> ignore
lviElement.SubItems.Add (sprintf "%s" element.AtomicMass) |> ignore

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

This would produce:

In the same way, you can keep calling the method to remove more elements. In the Set module, an alternative to the Set.Remove() method is a function named remove. Its signature is:

`Set.remove : 'T -> Set<'T> -> Set<'T>`
 A Duplicate Set

In algebra, after creating a set A, you may want to create another set B that contains the same elements as A. To do this, you can simply assign the original set (A) to the new one (B). This would be done as follows:

```A = { Kevin Walchild, Jane Overton, Daniel Albertson,
Ruth Oyawale, Jane Ouelette, Paul Sullivan }

B = A```

Now, sets A and B have the same elements:

Here is an example of creating a duplicate set:

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

let censusBureauNewEngland = set [ "Maine"; "Vermont"; "New Hampshire"; "Massachusetts"; "Rhode Island"; "Connecticut" ]

let getCount states : int =
Set.count states

let USRegions = new Form(MaximizeBox = false, Text = "US Regions",
ClientSize = new System.Drawing.Size(320, 185),
StartPosition = FormStartPosition.CenterScreen)

let lbxRegions = new ListBox(Location = new Point(12, 12),
Size = new System.Drawing.Size(295, 100),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Top ||| AnchorStyles.Right ||| AnchorStyles.Bottom))

let lblNumberOfStates = new Label(Size = new System.Drawing.Size(295, 28), Location = new Point(14, 115),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Bottom))

let btnDuplicate = new Button(Size = new System.Drawing.Size(295, 30),
Location = new Point(12, 145), Text = "Duplicate",
Anchor = (AnchorStyles.Left ||| AnchorStyles.Right ||| AnchorStyles.Bottom))

let display states caption =
lbxRegions.Items.Clear()

USRegions.Text <- caption + " - New England"
states |> Set.iter (fun state -> lbxRegions.Items.Add (sprintf "%s" state) |> ignore)

let total = getCount states
lblNumberOfStates.Text <- "Number of states in New England (" + caption + "): " + sprintf "%d" total

display censusBureauNewEngland "US Census Bureau"

let btnDuplicateClick e =
let bureauOfEconomicAnalysisNewEngland = censusBureauNewEngland

display bureauOfEconomicAnalysisNewEngland "Bureau of Economic Analysis"

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

Here is an example of running the program:

Once you have created the set, you can manipulate it as you see fit.

 A Union of Sets

Imagine you have two sets A and B defined as follows:

```A = { Kevin, Jane, Daniel }
B = { Raul, Kevin, Tiffany, Michael, Jane ```

Uniting two sets consists of adding them. In F#, you get the elements of each set and add them to create a new set. If there is an element that is found in both sets, only one of the duplicate elements is added to the new set. In algebra, this operation is written as follows:

`A ∪ B = { x|x ∈ A or x ∈ B `

This can be visually illustrated as follows:

To help you unite two sets, the Set class is equipped with the + operator. Its signature is:

`static member ( + ) : Set<'T> * Set<'T> -> Set<'T>`

The + operator takes a set on each part and it produces their union. Here is an example:

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

let censusBureauSouthAtlantic = set [ "Delaware"; "West Virginia"; "Maryland"; "Washington D.C.";
"Virginia"; "North Carolina"; "South Carolina"; "Georgia"; "Florida" ]
let bureauOfEconomicAnalysisSoutheast = set [ "West Virginia"; "Kentucky";
"Virginia"; "Tennessee"; "North Carolina";
"South Carolina"; "Arkansas"; "Louisiana";
"Mississippi"; "Alabama"; "Georgia"; "Florida"; ]

let union = censusBureauSouthAtlantic + bureauOfEconomicAnalysisSoutheast

let USRegions = new Form(MaximizeBox = false, Text = "US Regions",
ClientSize = new System.Drawing.Size(390, 285),
StartPosition = FormStartPosition.CenterScreen)

USRegions.Controls.Add(new Label(AutoSize = true, Location = new Point(12, 12),
Text = "US Census Bureau - South Atlantic Region"))

let lbxSouthAtlantic = new ListBox(Size = new System.Drawing.Size(365, 55),
Location = new Point(12, 32), MultiColumn = true)

USRegions.Controls.Add(new Label(AutoSize = true, Location = new Point(12, 85),
Text = "Bureau of Economic Analysis - Southeast Region"))

let lbxSoutheast = new ListBox(Size = new System.Drawing.Size(365, 65),
Location = new Point(12, 108), MultiColumn = true)

USRegions.Controls.Add(new Label(AutoSize = true, Location = new Point(12, 175),
Text = "Union of Both Regions"))

let lbxUnion = new ListBox(Size = new System.Drawing.Size(365, 75),
Location = new Point(12, 198), MultiColumn = true)

let display states =
lbxSouthAtlantic.Items.Clear()
states |> Set.iter (fun state -> lbxSouthAtlantic.Items.Add (sprintf "%s" state) |> ignore)

lbxSoutheast.Items.Clear()
bureauOfEconomicAnalysisSoutheast |> Set.iter (fun state -> lbxSoutheast.Items.Add (sprintf "%s" state) |> ignore)

lbxUnion.Items.Clear()
union |> Set.iter (fun state -> lbxUnion.Items.Add (sprintf "%s" state) |> ignore)
display censusBureauSouthAtlantic

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

This would produce:

In the same way, you can add as many sets as you want by using the + operator among them. Here is an example:

```let persons  = set [ "Kevin"; "William"; "Jane"; "Daniel"; "Ruth" ]
let people   = set [ "Antoinette"; "Jane"; "Joshua"; "William"; "Paul" ]
let teachers = set [ "Patrick"; "Ted"; "Jeffrey"; "Peter"; "Jeannette" ]
let students = set [ "Frank"; "Jeffrey"; "Jane"; "Robert" ]

let result = persons + people + teachers + students```

This would produce:

```Antoinette
Daniel
Frank
Jane
Jeannette
Jeffrey
Joshua
Kevin
Patrick
Paul
Peter
Robert
Ruth
Ted
William
The new set contains 15 elements```

As an alternative to the + operator, the Set module provides a function named union. Its signature is:

`Set.union : Set<'T> -> Set<'T> -> Set<'T>`

This function  takes two sets as arguments and it returns their union. Here is an example of calling this function:

```let persons = set [ "Kevin"; "William"; "Jane"; "Daniel"; "Ruth"; ]
let people = set [ "Antoinette"; "Jane"; "Joshua"; "William"; "Paul"; ]

let result = Set.union persons people```

In the same way, you can add or unite as many sets as you want. Since the List.union() function takes only two arguments, you can pass one of the arguments as its own call of the function. Here is an example:

```let persons  = set [ "Kevin"; "William"; "Jane"; "Daniel"; "Ruth" ]
let people   = set [ "Antoinette"; "Jane"; "Joshua"; "William"; "Paul" ]
let students = set [ "Frank"; "Jeffrey"; "Jane"; "Robert" ]

let result = Set.union (Set.union persons people) students```

This would produce:

```Antoinette
Daniel
Frank
Jane
Jeffrey
Joshua
Kevin
Paul
Robert
Ruth
William
The new set contains 11 elements```

Here is an example that unites four sets:

```let persons  = set [ "Kevin"; "William"; "Jane"; "Daniel"; "Ruth" ]
let people   = set [ "Antoinette"; "Jane"; "Joshua"; "William"; "Paul" ]
let teachers = set [ "Patrick"; "Ted"; "Jeffrey"; "Peter"; "Jeannette" ]
let students = set [ "Frank"; "Jeffrey"; "Jane"; "Robert" ]

let result = Set.union (Set.union (Set.union persons people) teachers) students```

It is important to know that this method performs a comparison on the elements of both sets so that the result would not allow any duplicate item.

 The Intersection of Two Sets

The intersection between two sets is the collection of only elements that belong to both sets. That is, the elements that belong to one set but do not belong to the other set are excluded. In algebra, we write it as follows:

`A ∩ B = { x|x ∈ A and x ∈ B `

This can be illustrated as follows:

To let you get the intersecting elements of two sets, the Set module provides a function named intersect. Its signature is:

`Set.intersect : Set<'T> -> Set<'T> -> Set<'T>`

This function takes two sets as arguments. It considers each element from one set and compares it to element from the other set. Any element that is found in both sets is included in the result that is a new set. Here is an example of calling this function:

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

let censusBureauSouthAtlantic = set [ "Delaware"; "West Virginia"; "Maryland"; "Washington D.C.";
"Virginia"; "North Carolina"; "South Carolina"; "Georgia"; "Florida" ]
let bureauOfEconomicAnalysisSoutheast = set [ "West Virginia"; "Kentucky";
"Virginia"; "Tennessee"; "North Carolina";
"South Carolina"; "Arkansas"; "Louisiana";
"Mississippi"; "Alabama"; "Georgia"; "Florida"; ]

let intersection = Set.intersect censusBureauSouthAtlantic bureauOfEconomicAnalysisSoutheast

let USRegions = new Form(MaximizeBox = false, Text = "US Regions",
ClientSize = new System.Drawing.Size(390, 245),
StartPosition = FormStartPosition.CenterScreen)

USRegions.Controls.Add(new Label(AutoSize = true, Location = new Point(12, 12),
Text = "US Census Bureau - South Atlantic Region"))

let lbxSouthAtlantic = new ListBox(Size = new System.Drawing.Size(365, 55),
Location = new Point(12, 32), MultiColumn = true)

USRegions.Controls.Add(new Label(AutoSize = true, Location = new Point(12, 85),
Text = "Bureau of Economic Analysis - Southeast Region"))

let lbxSoutheast = new ListBox(Size = new System.Drawing.Size(365, 65),
Location = new Point(12, 108), MultiColumn = true)

USRegions.Controls.Add(new Label(AutoSize = true, Location = new Point(12, 175),
Text = "Intersection of Both Regions"))

let lbxIntersection = new ListBox(Size = new System.Drawing.Size(365, 35),
Location = new Point(12, 198), MultiColumn = true)

let display states =
lbxSouthAtlantic.Items.Clear()
states |> Set.iter (fun state -> lbxSouthAtlantic.Items.Add (sprintf "%s" state) |> ignore)

lbxSoutheast.Items.Clear()
bureauOfEconomicAnalysisSoutheast |> Set.iter (fun state -> lbxSoutheast.Items.Add (sprintf "%s" state) |> ignore)

lbxIntersection.Items.Clear()
intersection |> Set.iter (fun state -> lbxIntersection.Items.Add (sprintf "%s" state) |> ignore)
display censusBureauSouthAtlantic

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

This would produce:

 Subtracting or Removing Elements from a Set

Consider two sets A and B. The difference between a set A from a set B is the list of elements that are found in set A but are not found in set B. In algebra, this is written as follows:

`A - B = { x|x ∈ A and x ∉ B `

This can be illustrated as follows:

To let you perform this operation, the Set class is equipped with the - operator. Its signature is:

`static member ( - ) : Set<'T> * Set<'T> -> Set<'T>`

Here is an example:

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

type ZoneInclusion = | Entirely | Split

type State = {
Name : string
Inclusion : ZoneInclusion }

let eastern = set [ { Name = "Maine";           Inclusion = Entirely }
{ Name = "Vermont";         Inclusion = Entirely }
{ Name = "New Hampshire";   Inclusion = Entirely }
{ Name = "Massachusetts";   Inclusion = Entirely }
{ Name = "Rhode Island";    Inclusion = Entirely }
{ Name = "Connecticut";     Inclusion = Entirely }
{ Name = "Michigan";        Inclusion = Split    }
{ Name = "New York";        Inclusion = Entirely }
{ Name = "New Jersey";      Inclusion = Entirely }
{ Name = "Indiana";         Inclusion = Split    }
{ Name = "Ohio";            Inclusion = Entirely }
{ Name = "Pennsylvania";    Inclusion = Entirely }
{ Name = "Delaware";        Inclusion = Entirely }
{ Name = "Maryland";        Inclusion = Entirely }
{ Name = "Washington D.C."; Inclusion = Entirely }
{ Name = "West Virginia";   Inclusion = Entirely }
{ Name = "Kentucky";        Inclusion = Split    }
{ Name = "Virginia";        Inclusion = Entirely }
{ Name = "Tennessee";       Inclusion = Split    }
{ Name = "North Carolina";  Inclusion = Entirely }
{ Name = "South Carolina";  Inclusion = Entirely }
{ Name = "Georgia";         Inclusion = Entirely }
{ Name = "Alabama";         Inclusion = Split    }
{ Name = "Florida";         Inclusion = Split    } ]

let timeManagement = new Form(MaximizeBox = false, Text = "Time Management",
ClientSize = new System.Drawing.Size(250, 250),
StartPosition = FormStartPosition.CenterScreen)

let lvwTimeZones = new ListView(GridLines = true, View = View.Details,
Size = new System.Drawing.Size(225, 144),
FullRowSelect = true, Location = new Point(12, 12),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Top ||| AnchorStyles.Right ||| AnchorStyles.Bottom))

let mutable col = lvwTimeZones.Columns.Add("State", 140)

let lblNumberOfStates = new Label(Size = new System.Drawing.Size(225, 38), Location = new Point(14, 170),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Bottom))

let btnRemove = new Button(Location = new Point(12, 215), Text = "Remove Non-State",
Anchor = (AnchorStyles.Left ||| AnchorStyles.Bottom), Width = 225)

let display zones =
lvwTimeZones.Items.Clear()

zones |> Set.iter (fun timeZone ->
let mutable lviTimeZone = new ListViewItem()
lviTimeZone.Text <- (sprintf "%s" timeZone.Name)
lviTimeZone.SubItems.Add (sprintf "%A" timeZone.Inclusion) |> ignore

lblNumberOfStates.Text <- "Number of states entirely or partially involved with Eastern Time Zone: " + sprintf "%d" zones.Count

display eastern

let btnRemoveClick e =
let states = eastern - set [{ Name = "Washington D.C."; Inclusion = Entirely }]
display states

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

This would produce:

On the other hand, the Set module provides a function named difference. Its signature is:

`Set.difference : Set<'T> -> Set<'T> -> Set<'T>`

This function takes two sets as arguments. Here is an example:

```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let people = set [ "Antoinette"; "Jane"; "Joshua"; "William"; "Paul" ]

let result = Set.difference persons people```

To let create a new set that contains elements from an existing set minus a certain element, the Set class is equipped with a method named Remove. Its signature is:

`member this.Remove : 'T -> Set<'T>`

This method takes one argument as the element to be removed from the set that called it. The method produces a new set. Here is an example:

```let btnRemoveClick e =
let states = eastern.Remove { Name = "Washington D.C."; Inclusion = Entirely }
display states```
 Deriving a Sub-Set from a Set

To create a new set that gets its element from an existing set, you can apply a condition by which the desired elements would be selected. To let you perform this operation, the Set module provides a function named filter. Its signature is:

`Set.filter : ('T -> bool) -> Set<'T> -> Set<'T>`

Here is an example:

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

type ZoneInclusion = | Entirely | Split

type State = {
Name : string
Inclusion : ZoneInclusion }

let eastern = set [ { Name = "Maine";           Inclusion = Entirely }
{ Name = "Vermont";         Inclusion = Entirely }
{ Name = "New Hampshire";   Inclusion = Entirely }
{ Name = "Massachusetts";   Inclusion = Entirely }
{ Name = "Rhode Island";    Inclusion = Entirely }
{ Name = "Connecticut";     Inclusion = Entirely }
{ Name = "Michigan";        Inclusion = Split    }
{ Name = "New York";        Inclusion = Entirely }
{ Name = "New Jersey";      Inclusion = Entirely }
{ Name = "Indiana";         Inclusion = Split    }
{ Name = "Ohio";            Inclusion = Entirely }
{ Name = "Pennsylvania";    Inclusion = Entirely }
{ Name = "Delaware";        Inclusion = Entirely }
{ Name = "Maryland";        Inclusion = Entirely }
{ Name = "Washington D.C."; Inclusion = Entirely }
{ Name = "West Virginia";   Inclusion = Entirely }
{ Name = "Kentucky";        Inclusion = Split    }
{ Name = "Virginia";        Inclusion = Entirely }
{ Name = "Tennessee";       Inclusion = Split    }
{ Name = "North Carolina";  Inclusion = Entirely }
{ Name = "South Carolina";  Inclusion = Entirely }
{ Name = "Georgia";         Inclusion = Entirely }
{ Name = "Alabama";         Inclusion = Split    }
{ Name = "Florida";         Inclusion = Split    } ]

let statesEntirelyInTimeZone = eastern |> Set.filter (fun (state : State) -> state.Inclusion = Entirely)

let timeManagement = new Form(MaximizeBox = false, Text = "Time Management",
ClientSize = new System.Drawing.Size(250, 210),
StartPosition = FormStartPosition.CenterScreen)

let lvwTimeZones = new ListView(GridLines = true, View = View.Details,
Size = new System.Drawing.Size(225, 144),
FullRowSelect = true, Location = new Point(12, 12),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Top ||| AnchorStyles.Right ||| AnchorStyles.Bottom))

let mutable col = lvwTimeZones.Columns.Add("State", 140)

let lblNumberOfStates = new Label(Size = new System.Drawing.Size(225, 38), Location = new Point(14, 170),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Bottom))

let display(zones) =
lvwTimeZones.Items.Clear()

zones |> Set.iter (fun timeZone ->
let mutable lviTimeZone = new ListViewItem()
lviTimeZone.Text <- (sprintf "%s" timeZone.Name)
lviTimeZone.SubItems.Add (sprintf "%A" timeZone.Inclusion) |> ignore

lblNumberOfStates.Text <- "Number of states entirely in the Eastern Time Zone: " + sprintf "%d" zones.Count

display statesEntirelyInTimeZone

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

This would produce:

 Mapping Some Elements of a Set

To let you perform an operation on each element of a set to get a new set, the Set module provides a function named map. Its signature is:

`Set.map : ('T -> 'U) -> Set<'T> -> Set<'U>`

Here is an example:

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

let xCoordinates = set [ -3; -2; -2; -1; 0; 1; 2; 3 ]

let yCoordinates = Set.map (fun x -> (x, 2 * x + 3)) xCoordinates

let geometry = new Form(MaximizeBox = false, Text = "Geometry",
ClientSize = new System.Drawing.Size(250, 180),
StartPosition = FormStartPosition.CenterScreen)

geometry.Controls.Add(new Label(Location = new Point(12, 12),
Size = new System.Drawing.Size(200, 30),
Text = "Equation: y = 2x + 3 Coordinates"))

let lvwCoordinates = new ListView(GridLines = true, View = View.Details,
Size = new System.Drawing.Size(225, 124),
FullRowSelect = true, Location = new Point(12, 42))

let mutable col = lvwCoordinates.Columns.Add("X", 40)

let display() =
lvwCoordinates.Items.Clear()

for point in yCoordinates do
let (a, b) = point

let lviCoordinate = new ListViewItem(sprintf "%i" a)

display()

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

This would produce:

 Partitioning a Set

To let you segment a set into two, the Set module provides a function named partition. Its signature is:

`Set.partition : ('T -> bool) -> Set<'T> -> Set<'T> * Set<'T>`

This function takes a function and a list as arguments. The function argument applies a condition to all members of the list. The function returns two lists. You can get the return value as two values or as a pair. Here is an example:

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

type ZoneInclusion = | Entirely | Split

type State = {
Name : string
Inclusion : ZoneInclusion }

let eastern = set [ { Name = "Maine";           Inclusion = Entirely }
{ Name = "Vermont";         Inclusion = Entirely }
{ Name = "New Hampshire";   Inclusion = Entirely }
{ Name = "Massachusetts";   Inclusion = Entirely }
{ Name = "Rhode Island";    Inclusion = Entirely }
{ Name = "Connecticut";     Inclusion = Entirely }
{ Name = "Michigan";        Inclusion = Split    }
{ Name = "New York";        Inclusion = Entirely }
{ Name = "New Jersey";      Inclusion = Entirely }
{ Name = "Indiana";         Inclusion = Split    }
{ Name = "Ohio";            Inclusion = Entirely }
{ Name = "Pennsylvania";    Inclusion = Entirely }
{ Name = "Delaware";        Inclusion = Entirely }
{ Name = "Maryland";        Inclusion = Entirely }
{ Name = "Washington D.C."; Inclusion = Entirely }
{ Name = "West Virginia";   Inclusion = Entirely }
{ Name = "Kentucky";        Inclusion = Split    }
{ Name = "Virginia";        Inclusion = Entirely }
{ Name = "Tennessee";       Inclusion = Split    }
{ Name = "North Carolina";  Inclusion = Entirely }
{ Name = "South Carolina";  Inclusion = Entirely }
{ Name = "Georgia";         Inclusion = Entirely }
{ Name = "Alabama";         Inclusion = Split    }
{ Name = "Florida";         Inclusion = Split    } ]

let entirety, others = eastern |> Set.partition (fun (state : State) -> state.Inclusion = Entirely)

let timeManagement = new Form(MaximizeBox = false, Text = "Time Management",
ClientSize = new System.Drawing.Size(250, 425),
StartPosition = FormStartPosition.CenterScreen)

let lvwEntirely = new ListView(GridLines = true, View = View.Details,
Size = new System.Drawing.Size(225, 280),
FullRowSelect = true, Location = new Point(12, 12),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Top ||| AnchorStyles.Right))
let mutable col = lvwEntirely.Columns.Add("State", 140)

let lvwOthers = new ListView(GridLines = true, View = View.Details,
Size = new System.Drawing.Size(225, 110),
FullRowSelect = true, Location = new Point(12, 305),
Anchor = (AnchorStyles.Left ||| AnchorStyles.Top ||| AnchorStyles.Right ||| AnchorStyles.Bottom))

let display() =
lvwEntirely.Items.Clear()
lvwOthers.Items.Clear()

entirety |> Set.iter (fun timeZone ->
let mutable lviTimeZone = new ListViewItem()
lviTimeZone.Text <- (sprintf "%s" timeZone.Name)
lviTimeZone.SubItems.Add (sprintf "%A" timeZone.Inclusion) |> ignore

others |> Set.iter (fun timeZone ->
let mutable lviTimeZone = new ListViewItem()
lviTimeZone.Text <- (sprintf "%s" timeZone.Name)
lviTimeZone.SubItems.Add (sprintf "%A" timeZone.Inclusion) |> ignore

display()

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

This would produce:

 Boolean Operations on Sets

 Checking Whether an Element Exists

To let you check whether an element exists in a set, the Set module contains a function named exists. Its signature is:

`Set.exists : ('T -> bool) -> Set<'T> -> bool`

Here is an example of calling this method:

```let foodMenu = set [ "Sweet and Sour Chicken"
"Scallion Beef"
"Cashew Chicken"
"Wonton Soup"
"Kung Pao Chicken"
"Egg Roll"
"Szechuan Chicken"
"Shrimp Lobster Sauce"
"Hunan Chicken" ]

let restaurantHasWontonSoup = Set.exists (fun item -> item = "Wonton Soup") foodMenu```

This would produce:

`Does the restaurant serve Wonton Soup? Yes`
 Checking a Condition for all Elements of a Set

To let you find out whether all elements of a set respond to a certain condition, the Set module provides a function named forall. Its signature is:

`Set.forall : ('T -> bool) -> Set<'T> -> bool`

Here are examples of calling this function:

```let foodMenu = set [ "LS01: Sweet and Sour Chicken"
"CS01: Scallion Beef"
"LS02: Cashew Chicken"
"SP01: Wonton Soup"
"LS03: Kung Pao Chicken"
"AP01: Egg Roll"
"LS04: Szechuan Chicken"
"SP02: Shrimp Lobster Sauce"
"CS02: Hunan Chicken" ]

let lunchSpecial = set [ "LS01: Sweet and Sour Chicken"
"LS02: Cashew Chicken"
"LS03: Kung Pao Chicken"
"LS04: Szechuan Chicken" ]

let menu1IsForLunchSpecial = Set.forall (fun (item : string) -> item.StartsWith "LS") foodMenu
let menu2IsForLunchSpecial = Set.forall (fun (item : string) -> item.StartsWith "LS") lunchSpecial

| true -> sprintf "Yes, this menu is for lunch special only"
| false -> sprintf "No, this the restaurant's whole menu"

| true -> sprintf "Yes, this menu is for lunch special only"
| false -> sprintf "No, this the restaurant's whole menu"```
 Comparing Sets For Equality

Imagine you have two sets A and B defined as follows:

```A = { Kevin Walchild, Jane Overton, Daniel Albertson, Jane Ouelette }
B = { Daniel Albertson, Kevin Walchild, Jane Ouelette, Jane Overton ```

Notice that both sets have the same elements. When two sets have exact same elements, we say that those sets are equal. This can be expressed as:

`A = B`

This operation is commutative, which means the above operation can also be written as:

`B = A`

To compare two sets for equality, simply use the = operator. Here is an example:

```let names = set [ "Kevin"; "Jane"; "Daniel"; "James"; "Ruth"; "Paul"; ]
let students = set [ "Kevin"; "Jane"; "William"; "Daniel"; "James"; "Ruth"; "Paul"; ]

if Set.isEmpty names then
sprintf "The set is empty"
else
let duplicate = names = students
if duplicate then
sprintf "Both sets are the same"
else
sprintf "The sets are different"```
 Checking Whether a Set Contains a Certain Element

In algebra, to show that a certain element "a" exists in a set A, we would write:

`a ∈ A`

This is read as "a is an element of set A" or "a is included in set A" or "Set A contains a". To support this operation, the Set class is equippede with a method named Contains. Its signature is:

`member this.Contains : 'T -> bool`

This function is called on a Set variable. Here is an example:

```let names = set [ "Kevin"; "Jane"; "Daniel"; "James"; "Ruth"; "Paul" ]

if Set.isEmpty names then
sprintf "The set is empty"
else
let name = names.Contains "Daniel"
if name then
sprintf "Daniel is in the set"
else
sprintf "Daniel is not in the set"```

As an alternative, the Set module provides a function named contains. Its signature is:

`Set.contains : 'T -> Set<'T> -> bool`

Here is an example:

```let lunchSpecial = set [ "Sweet and Sour Chicken"
"Cashew Chicken"
"Kung Pao Chicken"
"Szechuan Chicken"
"Hunan Chicken" ]

let verify = Set.contains  "Cashew Chicken" lunchSpecial```

In algebra, to state that an element a is not in the set A, we write:

`a ∉ A`

This reads as "a is not an element of set A" or "a is not included in set A" or "Set A does not contain a". To perform this checking in programming, you can use the NOT Boolean operator "!".

 A Subset of Another Set

A set A is a sub-set of another set B if all elements of Set A can be found in Set B. This is expressed in algebra as:

`A ⊂ B`

This is the same as:

` { Kevin, Jane, Daniel } ⊂ { Raul, Kevin, Tiffany, Daniel, Michael, Jane, Paul `

This can be illustrated as follows:

In algebra, any set is a subset of itself. Also, since the empty set doesn't have any element, the empty set is a subset of any set. We write it as:

`∅ ⊂ A`

and

`∅ ⊂ B`

An empty set is also a subset of itself.

To let you find out whether one set is a subset of another, the Set class is equipped with a method named IsSubsetOf. Its signature is:

`member this.IsSubsetOf : Set<'T> -> bool`

This method is applied to a set variable that calls it. The method takes one argument as the set to check. If all elements if the argument are found in the set variable that called this method, the method returns true. If at least one member of the argument is not found in the set variable, the method returns false. Here is an example of calling this method:

```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let students = set [ "Jane"; "William" ]

let result = students.IsSubsetOf persons

sprintf "Set Student is a subset of set Persons: %A " result```

As an alternative, the Set module provides a function named isSubset. Its signature is:

`Set.isSubset : Set<'T> -> Set<'T> -> bool`

This function takes two arguments as the sets to be compared. If all elements of the first argument are found in the second argument, the function returns true. If not, it returns false. Here is an example:

```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let students = set [ "Jane"; "William" ]

let result = Set.isSubset students persons```

It is important to know that the subset relationship is one way; in other words, the comparison is not commutative: the fact that a set A is a subset of a set B is not vice-versa.

 A Proper Subset of Another Set

A set is a subset of itself. Also, when two sets have the exact same members, each set is a subset of the other:

On the other hand, if you have a set A that is strictly a subset of another set B, this means there is at least one element in set B that is not a member of set A. In this case, we say that set A is a property subset of set B. This can be illustrated as follows:

To let you find out if a set is a proper subset of another set, the Set class is equipped with a method named IsProperSubsetOf. Its signature is:

`member this.IsProperSubsetOf : Set<'T> -> bool`

This method takes a Set value as arguments and performs a comparison on their elements:

• If both sets are the same, the method returns false. Here is an example:
```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let students = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]

let result = students.IsProperSubsetOf persons```
If the argument has at least one element that is not in the variable that called it, the method returns false. Here is an example:
```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let students = set [ "Antoinette"; "Jane"; "William" ]

let result = students.IsProperSubsetOf persons```
If all elements of the argument's set are members of the variable that called it, the method returns true. Here is an example:
```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let students = set [ "Jane"; "William" ]

let result = students.IsProperSubsetOf persons```

As an alternative to the Set.IsProperSubsetOf() method, the Set module provides a function named isProperSubset. Its signature is:

`Set.isProperSubset : Set<'T> -> Set<'T> -> bool`

This function takes two arguments as the sets to compare but it works the same way as the Set.IsProperSubsetOf() method.

 A Super-Set of an Existing Set

Remember that a sub-set is a set whose all elements are also found in another set. A super-set is the reverse of a sub-set. That is, in a superset, all the elements of a set B are found in a set A but set A may have elements that are not found in set B. In algebra, this can be written as follows:

`B ⊃ A`

To help you make this comparison, the Set class is equipped with a method named IsSupersetOf. Its syntax is:

`member this.IsSupersetOf : Set<'T> -> bool`

This method takes a Set collection as argument and compares its elements to those of the variable that called it. If all the elements of the argument are found in the variable that called it, the method returns true. Here is an example:

```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let students = set [ "Jane"; "William" ]

let result = persons.IsSupersetOf students```

This would produce:

`Set Persons is a super set of set Student: true`

As an alternative to the Set.IsSupersetOf() method, the Set module provides a function named isSuperset. Its signature is:

`Set.isProperSubset : Set<'T> -> Set<'T> -> bool`

This function takes two arguments as the sets to compare but it works the same way as the Set.IsSupersetOf() method.

 A Proper Super-Set of an Existing Set

When it comes to a super-set, if two sets are the same, each one is considered a super-set of the other and the IsSupersetOf() method returns true. By contrast, if a set B is a super-set of A but both sets are not the same, that is, set B has more elements than set A, set B is said to be a property super-set of A. To let you make the comparison to determine this, the Set class is equipped with a method named IsProperSupersetOf. Its syntax is:

`member this.IsProperSupersetOf : Set<'T> -> bool`

This method works as follows:

• If both sets are the same, the method returns false. Here is an example:
```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let students = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]

let result = persons.IsProperSupersetOf students```
This would produce:
`Set Persons is a proper super set of set Students: false`
• If the argument has at least one element that is not in the variable that called it, the method returns false. Here is an example:
```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let students = set [ "Antoinette"; "Jane"; "William" ]

let result = persons.IsProperSupersetOf students```
This would produce:
`Set Persons is a proper super set of set Students: false`
• If all elements of the argument's set are members of the variable that called it, the method returns true. Here is an example:
```let persons = set [ "Kevin"; "William"; "Rebeccah"; "Jane"; "Daniel"; "Ruth" ]
let students = set [ "Jane"; "William" ]

let result = persons.IsProperSupersetOf students```
This would produce:
`Set Persons is a proper super set of set Students: true`

To let you perform this same operation, the Set module provides a function named isProperSuperset. Its signature is:

`Set.isProperSuperset : Set<'T> -> Set<'T> -> bool`
 Sets and Other Collection Types

 Introduction

You can create a set from any of the other F# collections. To support the other collections, the Set module provides an appropriate function. After creating the set from the other collection, all of the methods of the Set class and those from the Set module are available.

 Creating a Set from a List

To let you create a set from a list, the Set module provides a function named ofList. Its signature is:

`Set.ofList : 'T list -> Set<'T>`

Here is an example:

```let lstNumbers = [ 2 .. 2 .. 20 ]
let lstSomeEquares = [ 4; 16 ]

let setNumbers = Set.ofList lstNumbers
let setSomeEquares = Set.ofList lstSomeEquares
let sub = setSomeEquares.IsSubsetOf setNumbers```
 Creating a Set from an Array

To let you create a set from an existing array, the Set module provides a function named ofArray. Its signature is:

`Set.ofArray : 'T array -> Set<'T>`

Here is an example:

```let arNames  : string array = [| "James"; "April"; "Annette"; "Hughs"; "June"; "Daniel"; "Martine" |]
let arMonths : string array = [| "January"; "February"; "Mars"; "April"; "May"; "June"; "July" |]

let setNames  = Set.ofArray arNames
let setMonths = Set.ofArray arMonths```