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 (https://github.com/dotnet/fsharp/blob/main/src/FSharp.Core/set.fs).

Creating a set consists of adding elements to it. This can be illustrated as follows:

Creating a Set

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 an alternative, 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 must 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" ]

printfn "Names: %A" set;

This would produce:

Names: set ["Daniel"; "Jane"; "Kevin"; "Paul"; "Ruth"]

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

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

for i in names do
    printfn "Name: %s" i;

This would produce:

Name: Daniel
Name: Jane
Name: Kevin
Name: Paul
Name: Ruth
Press any key to close this window . . .

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 letter 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:

Set

To create an empty set, declare a variable and assign the empty property of the Set module 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:

let names = set []

if Set.isEmpty names then
    printfn "The set is empty"
else
    for i in names do
        printfn "Names: %s" i

This would produce:

The set is empty
Press any key to close this window . . .

As an alternative, the Set module 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:

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

for food in lunchSpecial do
        printfn "Food Item: %s" food

printfn "-------------------------------"
let length = Set.count lunchSpecial

printfn "The food menu contains %d items" length

This would produce:

Food Item: Cashew Chicken
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
-------------------------------
The food menu contains 5 items
Press any key to close this window . . .

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

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

printfn "The set contains %i elements" names.Count

This would produce:

The set contains 6 elements
Press any key to close this window . . .

A Set is Automatically Sorted

After a set has been created, every time before it is used, the compiler first and 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 ]

printfn "Numbers: %A" series

This would produce:

Numbers: set [3; 8; 20; 40; 93; 405]
Press any key to close this window . . .

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" ]

for i in names do
    printfn "Name: %s" i;

This would produce:

Name: Daniel
Name: Jane
Name: Kevin
Name: Paul
Name: Ruth

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

open System

let dates = set [ new DateTime(2015, 6, 8);
		  new DateTime(2015, 4, 6);
		  new DateTime(2015, 7, 6);
		  new DateTime(2015, 5, 4) ]

for date in dates do
    printfn "First Monday of Month: %s\t\t%s" (date.ToShortDateString()) (date.ToLongDateString())

This would produce:

First Monday of Month: 4/6/2015		Monday, April 06, 2015
First Monday of Month: 5/4/2015		Monday, May 04, 2015
First Monday of Month: 6/8/2015		Monday, June 08, 2015
First Monday of Month: 7/6/2015		Monday, July 06, 2015
Press any key to close this window . . .

No Duplicate Value in a Set

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

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

if Set.isEmpty names then
    printfn "The set is empty"
else
    for i in names do
        printfn "Name: %s" i

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

Name: Daniel
Name: James
Name: Jane
Name: Kevin
Name: Paul
Name: Ruth
Press any key to close this window . . .

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 its 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 module is equipped with a property named MinimumElement. Here is an example of accessing it:

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

printfn "Original Set"
for number in numbers do printfn "Number %i" number

printfn "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="

let highest = numbers.MinimumElement

printfn "The highest number of the set is %i" highest

This would produce:

Original Set
Number 2
Number 4
Number 10
Number 30
Number 48
Number 80
Number 830
Number 38482
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
The lowest value of the Number set is 2
Press any key to close this window . . .

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"; ]

for food in lunchSpecial do
        printfn "Food Item: %s" food

printfn "-------------------------------"
let first = Set.minElement lunchSpecial

printfn "The first food item is named %s" first

This would produce:

Food Item: Cashew Chicken
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
-------------------------------
The first food item is named Cashew Chicken
Press any key to close this window . . .

The Highest Element in a Set

To let you get the highest element in a set, the Set module 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 ]

printfn "Original Set"
for number in numbers do printfn "Number %i" number

printfn "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="

let highest = numbers.MaximumElement

printfn "The highest number of the set is %i" highest

This would produce:

Original Set
Number 2
Number 4
Number 10
Number 30
Number 48
Number 80
Number 830
Number 38482
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
The highest number of the set is 38482
Press any key to close this window . . .

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"; ]

for food in lunchSpecial do
        printfn "Food Item: %s" food

printfn "-------------------------------"
let last = Set.maxElement lunchSpecial

printfn "The last food item is named %s" last

This would produce:

Food Item: Cashew Chicken
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
-------------------------------
The last food item is named Szechuan Chicken
Press any key to close this window . . .

Fundamental Operations on a Set

Creating 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

printfn "Number: %A" nbr

This wold produce:

Number: set [248]
Press any key to close this window . . .

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:

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" ]

printfn "Restaurant Food Menu"
printfn "______________________________________"
Set.iter (fun item -> printfn "Food Item: %s" item) foodMenu

This would produce:

Restaurant Food Menu
______________________________________
Food Item: Cashew Chicken
Food Item: Egg Roll
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Scallion Beef
Food Item: Shrimp Lobster Sauce
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
Food Item: Wonton Soup
Press any key to close this window . . .

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 module is equipped with a function named Add. Its signature is:

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

This function takes one argument as the item to be added to the set that called it. Here is an example:

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

for food in lunchSpecial do
        printfn "Food Item: %s" food

printfn "The food menu contains %d items" lunchSpecial.Count
printfn "------------------------------------"

let updated = lunchSpecial.Add "Moo Goo Gai Pan"

for food in lunchSpecial do
        printfn "Food Item: %s" food

printfn "The updated food menu contains %d items" updated.Count
printfn "------------------------------------"

This would produce:

Food Item: Cashew Chicken
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
The food menu contains 5 items
------------------------------------
Food Item: Cashew Chicken
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Moo Goo Gai Pan
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
The updated food menu contains 6 items
------------------------------------
Press any key to close this window . . .

Because the Set.Add() function 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:

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

for food in lunchSpecial do
        printfn "Food Item: %s" food

printfn "The food menu contains %d items" lunchSpecial.Count
printfn "------------------------------------";

let updated = ((lunchSpecial.Add "Moo Goo Gai Pan").Add "General Tso's Chicken").Add "Broccoli Chicken"

for food in updated do
        printfn "Food Item: %s" food

printfn "The updated food menu contains %d items" updated.Count
printfn "------------------------------------";

This would produce:

Food Item: Cashew Chicken
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
The food menu contains 5 items
------------------------------------
Food Item: Broccoli Chicken
Food Item: Cashew Chicken
Food Item: General Tso's Chicken
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Moo Goo Gai Pan
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
The updated food menu contains 8 items
------------------------------------
Press any key to close this window . . .

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

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

printfn "Original Set"
for number in numbers do printfn "Number %i" number

printfn "=-=-=-=-=-=-=-=-=-=-=-=-="
let updated = Set.add 666 numbers

printfn "New Set"
for number in updated do printfn "Number %i" number

This would produce:

Original Set
Number 2
Number 4
Number 10
Number 30
Number 48
Number 80
Number 830
Number 38482
=-=-=-=-=-=-=-=-=-=-=-=-=
New Set
Number 2
Number 4
Number 10
Number 30
Number 48
Number 80
Number 666
Number 830
Number 38482
Press any key to close this window . . .

In the same way, you can keep calling the Set.add() function to add as many elements as you want. Here is an example that creates a new set made of elements from an existing set and additional elements:

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

printfn "Original Set"
for number in numbers do printfn "Number %i" number

printfn "=-=-=-=-=-=-=-=-=-=-=-=-="

let updated = Set.add  1008592 (Set.add 1407 (Set.add 666 numbers))

printfn "New Set"
for number in updated do printfn "Number %i" number

This would produce:

Original Set
Number 2
Number 4
Number 10
Number 30
Number 48
Number 80
Number 830
Number 38482
=-=-=-=-=-=-=-=-=-=-=-=-=
New Set
Number 2
Number 4
Number 10
Number 30
Number 48
Number 80
Number 666
Number 830
Number 1407
Number 38482
Number 1008592
Press any key to close this window . . .

Removing an Element from a Set

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

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

This function 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 lunchSpecial = set [ "Sweet and Sour Chicken"
                         "Cashew Chicken"
                         "Kung Pao Chicken"
                         "Szechuan Chicken"
                         "Hot and Sour Soup"
                         "Hunan Chicken" ]

printfn "Original Food Menu"

for food in lunchSpecial do
        printfn "Food Item: %s" food

printfn "-------------------------------"
let onlyLunchSpecial = lunchSpecial.Remove "Hot and Sour Soup"

printfn "After removing the Hot and Sour Soup, the new food menu is"

for food in onlyLunchSpecial do
        printfn "Food Item: %s" food

This would produce:

Original Food Menu
Food Item: Cashew Chicken
Food Item: Hot and Sour Soup
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
-------------------------------
After removing the Hot and Sour Soup, the new food menu is
Food Item: Cashew Chicken
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
Press any key to close this window . . .

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

Set.remove : 'T -> Set<'T> -> Set<'T>

Creating 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:

Set

Here is an example of creating a duplicate set:

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

let students = names

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

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

A union of two sets is the list of all elements that belong to both sets. Remember that there is no reason to include an element twice if it already belongs to one of the sets. In algebra, this operation is written as follows:

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

This can be visually illustrated as follows:

A Union of Two Sets

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:

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

for person in persons do
        printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

let people = set [ "Antoinette"; "Jane"; "Joshua"; "William"; "Paul"; ]

for person in people do
    printfn "%s" person;

printfn "The set of people contains %d elements" people.Count
printfn "------------------------------------"

let result = persons + people

for str in result do
    printfn "%s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------";

This would produce:

Name: Daniel
Name: Jane
Name: Kevin
Name: Ruth
Name: William
The set of Persons contains 5 elements
------------------------------------
Antoinette
Jane
Joshua
Paul
William
The set of people contains 5 elements
------------------------------------
Antoinette
Daniel
Jane
Joshua
Kevin
Paul
Ruth
William
The new set contains 8 elements.
------------------------------------
Press any key to close this window . . .

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" ]

for person in persons do
        printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

for person in people do
    printfn "%s" person;

printfn "The set of people contains %d elements" people.Count
printfn "------------------------------------"

let result = persons + people + teachers + students

for str in result do
    printfn "%s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------"

This would produce:

Name: Daniel
Name: Jane
Name: Kevin
Name: Ruth
Name: William
The set of Persons contains 5 elements
------------------------------------
Antoinette
Jane
Joshua
Paul
William
The set of people contains 5 elements
------------------------------------
Antoinette
Daniel
Frank
Jane
Jeannette
Jeffrey
Joshua
Kevin
Patrick
Paul
Peter
Robert
Ruth
Ted
William
The new set contains 15 elements.
------------------------------------
Press any key to close this window . . .

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"; ]

for person in persons do
        printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

let people = set [ "Antoinette"; "Jane"; "Joshua"; "William"; "Paul"; ]

for person in people do
    printfn "%s" person;

printfn "The set of people contains %d elements" people.Count
printfn "------------------------------------"

let result = Set.union persons people

for str in result do
    printfn "%s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------";

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" ]

for person in persons do
        printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

for person in people do
    printfn "%s" person;

printfn "The set of people contains %d elements" people.Count
printfn "------------------------------------"

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

for str in result do
    printfn "%s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------";

This would produce:

Name: Daniel
Name: Jane
Name: Kevin
Name: Ruth
Name: William
The set of Persons contains 5 elements
------------------------------------
Antoinette
Jane
Joshua
Paul
William
The set of people contains 5 elements
------------------------------------
Antoinette
Daniel
Frank
Jane
Jeffrey
Joshua
Kevin
Paul
Robert
Ruth
William
The new set contains 11 elements.
------------------------------------
Press any key to close this window . . .

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" ]

for person in persons do
        printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";


for person in people do
    printfn "%s" person;

printfn "The set of people contains %d elements" people.Count
printfn "------------------------------------"

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

for str in result do
    printfn "%s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------";

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

Getting 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:

An Intersection of Two Sets

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 compares the elements from both sets and adds their elements in a new set that it will return. Any element that is found in both sets is excluded from the result. Here is an example of calling this function:

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

for person in persons do
    printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

for person in people do
    printfn "Name: %s" person;

printfn "The set of people contains %d elements" people.Count
printfn "------------------------------------"

printfn "The elements found in both sets are:"

let result = Set.intersect persons people

for str in result do
    printfn "Name: %s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------";

This would produce:

Name: Daniel
Name: Jane
Name: Kevin
Name: Rebeccah
Name: Ruth
Name: William
The set of Persons contains 6 elements
------------------------------------
Name: Antoinette
Name: Jane
Name: Joshua
Name: Paul
Name: William
The set of people contains 5 elements
------------------------------------
The elements found in both sets are:
Name: Jane
Name: William
The new set contains 2 elements.
------------------------------------
Press any key to close this window . . .

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:

The Difference of Two Sets

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

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

Here is an example:

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

for person in persons do
    printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

for person in people do
    printfn "Name: %s" person;

printfn "The set of people contains %d elements" people.Count
printfn "------------------------------------"

let result = persons - people

for str in result do
    printfn "Name: %s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------";

This would produce:

Name: Daniel
Name: Jane
Name: Kevin
Name: Rebeccah
Name: Ruth
Name: William
The set of Persons contains 6 elements
------------------------------------
Name: Antoinette
Name: Jane
Name: Joshua
Name: Paul
Name: William
The set of people contains 5 elements
------------------------------------
Name: Daniel
Name: Kevin
Name: Rebeccah
Name: Ruth
The new set contains 4 elements.
------------------------------------
Press any key to close this window . . .

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" ]

for person in persons do
    printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

for person in people do
    printfn "Name: %s" person;

printfn "The set of people contains %d elements" people.Count
printfn "------------------------------------"

let result = Set.difference persons people

for str in result do
    printfn "Name: %s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------"

Removing an Element from a Set

To let you remove an element from a set, the Set module provides a function named remove. Its signature is:

Set.remove : 'T -> Set<'T> -> Set<'T>

This function takes two arguments. The first argument is the element to be removed from the second argument that is a set. Here is an example:

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

printfn "Elements from Persons Set:"
for person in persons do
    printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

let result = Set.remove "William" persons

printfn "After removing element William from Set Person, the Person now contains:"
for str in result do
    printfn "Name: %s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------";

This would produce:

lements from Persons Set:
ame: Daniel
ame: Jane
ame: Kevin
ame: Rebeccah
ame: Ruth
ame: William
he set of Persons contains 6 elements
-----------------------------------
fter removing element William from Set Person, the Person now contains:
ame: Daniel
ame: Jane
ame: Kevin
ame: Rebeccah
ame: Ruth
he new set contains 5 elements.
-----------------------------------
ress any key to continue . . .

If you have many elements you want to remove from a set, you can keep getting a set from calling the Set.remove() function and applying the new element to remove from it. Here is an example that removes two elements:

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

printfn "Elements from Persons Set:"
for person in persons do
    printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

let result = Set.remove "Daniel" (Set.remove "William" persons)

printfn "After removing element William from Set Person, the Person now contains:"
for str in result do
    printfn "Name: %s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------";

This would produce:

Elements from Persons Set:
Name: Daniel
Name: Jane
Name: Kevin
Name: Rebeccah
Name: Ruth
Name: William
The set of Persons contains 6 elements
------------------------------------
After removing element William from Set Person, the Person now contains:
Name: Jane
Name: Kevin
Name: Rebeccah
Name: Ruth
The new set contains 4 elements.
------------------------------------
Press any key to close this window . . .

In the same, you can keep calling the function to remove more elements. Here is an example that removes four elements:

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

printfn "Elements from Persons Set:"
for person in persons do
    printfn "Name: %s" person

printfn "The set of Persons contains %d elements" persons.Count
printfn "------------------------------------";

let result = Set.remove "Kevin" (Set.remove "Rebeccah" (Set.remove "Daniel" (Set.remove "William" persons)))

printfn "After removing Kevin, Rebeccah, Daniel, and William from the Person set, Set Persons now contains:"
for str in result do
    printfn "Name: %s" str

printfn "The new set contains %i elements." result.Count
printfn "------------------------------------";

This would produce:

lements from Persons Set:
ame: Daniel
ame: Jane
ame: Kevin
ame: Rebeccah
ame: Ruth
ame: William
he set of Persons contains 6 elements
-----------------------------------
fter removing element William from Set Person, the Person now contains:
ame: Jane
ame: Ruth
he new set contains 2 elements.
-----------------------------------
Press any key to close this window . . .

Deriving a 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:

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" ]

printfn "Original Restaurant Food Menu"

for food in foodMenu do
        printfn "Food Item: %s" food
printfn "-------------------------------------------"

let lunchSpecial = Set.filter (fun (item : string) -> item.StartsWith "LS") foodMenu
printfn "Original Restaurant Food Menu"

for food in lunchSpecial do
        printfn "Food Item: %s" food

This would produce:

Original Restaurant Food Menu
Food Item: AP01: Egg Roll
Food Item: CS01: Scallion Beef
Food Item: CS02: Hunan Chicken
Food Item: LS01: Sweet and Sour Chicken
Food Item: LS02: Cashew Chicken
Food Item: LS03: Kung Pao Chicken
Food Item: LS04: Szechuan Chicken
Food Item: SP01: Wonton Soup
Food Item: SP02: Shrimp Lobster Sauce
-------------------------------------------
Original Restaurant Food Menu
Food Item: LS01: Sweet and Sour Chicken
Food Item: LS02: Cashew Chicken
Food Item: LS03: Kung Pao Chicken
Food Item: LS04: Szechuan Chicken
Press any key to close this window . . .

Mapping Some Elements of a Set

To let you apply a condition to each element and extract a sub-set, the Set module provides a function named map. Its signature is:

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

Here is an example:

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

let prices = Set.map (fun item -> item + " $5.75") foodMenu
printfn "Restaurant Food Menu"
printfn "_____________________________________________"
Set.iter (fun item -> printfn "Food Item: %s" item) prices

This would produce:

Restaurant Food Menu
_____________________________________________
Food Item: LS01: Sweet and Sour Chicken $5.75
Food Item: LS02: Cashew Chicken         $5.75
Food Item: LS03: Kung Pao Chicken       $5.75
Food Item: LS04: Szechuan Chicken       $5.75
Food Item: LS05: Hunan Chicken          $5.75
Press any key to close this window . . .

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:

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

printfn "Original Set"
for number in numbers do printfn "Number %i" number

printfn "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="

let divisibleBy10, others = Set.partition (fun nbr -> nbr % 10 = 0) numbers

printfn "The set of numbers divisible by 10 is %A" divisibleBy10
printfn "The set of numbers not divisible by 10 is %A" others

This would produce:

Original Set
Number 2
Number 4
Number 10
Number 30
Number 48
Number 80
Number 830
Number 38482
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
The set of numbers divisible by 10 is set [10; 30; 80; 830]
The set of numbers not divisible by 10 is set [2; 4; 48; 38482]
Press any key to close this window . . .

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 function:

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" ]

printfn "Restaurant Food Menu"

for food in foodMenu do
        printfn "Food Item: %s" food

printfn "-------------------------------------------"

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

printf "Does the restaurant serve Wonton Soup? "
if restaurantHasWontonSoup = true then printfn "Yes" else printfn "No"

This would produce:

Restaurant Food Menu
Food Item: Cashew Chicken
Food Item: Egg Roll
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Scallion Beef
Food Item: Shrimp Lobster Sauce
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
Food Item: Wonton Soup
-------------------------------------------
Does the restaurant serve Wonton Soup? Yes
Press any key to close this window . . .

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 function 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

printf "Is this menu for lunch special only? "
match menu1IsForLunchSpecial with
| true -> printfn "Yes, this menu is for lunch special only"
| false -> printfn "No, this the restaurant's whole menu"

printfn "------------------------------------"
printf "Is this menu for lunch special only? "
match menu2IsForLunchSpecial with
| true -> printfn "Yes, this menu is for lunch special only"
| false -> printfn "No, this the restaurant's whole menu"

This would produce:

Is this menu for lunch special only? No, this the restaurant's whole menu
------------------------------------
Is this menu for lunch special only? Yes, this menu is for lunch special only
Press any key to close this window . . .

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
    printfn "The set is empty"
else
    let duplicate = names = students
    if duplicate then
        printfn "Both sets are the same"
    else
        printfn "The sets are different"

This would produce:

The sets are different
Press any key to close this window . . .

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 module is equippede with a function 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
    printfn "The set is empty"
else
    let name = names.Contains "Daniel"
    if name then
        printfn "Daniel is in the set"
    else
        printfn "Daniel is not in the set"

This would produce:

Daniel is in the set
Press any key to close this window . . .

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" ]

printfn "Restaurant Food Menu"

for food in lunchSpecial do
        printfn "Food Item: %s" food

printfn "-------------------------------"
let verify = Set.contains  "Cashew Chicken" lunchSpecial

printf "Does the food menu contain Cashew Chicken? "
if verify then
    printfn "Yes"
else
    printfn "No"

This would produce:

Restaurant Food Menu
Food Item: Cashew Chicken
Food Item: Hunan Chicken
Food Item: Kung Pao Chicken
Food Item: Sweet and Sour Chicken
Food Item: Szechuan Chicken
-------------------------------
Does the food menu contain Cashew Chicken? Yes
Press any key to close this window . . .

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 subset of another 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:

A Sub-Set of an Existing Set

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 function named IsSubsetOf. Its signature is:

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

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

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

printfn "Elements from Persons Set:"
for person in persons do
    printfn "Name: %s" person
    
printfn "------------------------------------"
printfn "Elements from Students Set:"
for std in students do
    printfn "Name: %s" std

printfn "------------------------------------"

let result = students.IsSubsetOf persons

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

This would produce:

Elements from Persons Set:
Name: Daniel
Name: Jane
Name: Kevin
Name: Rebeccah
Name: Ruth
Name: William
------------------------------------
Elements from Students Set:
Name: Jane
Name: William
------------------------------------
Set Student is a subset of set Persons: true
Press any key to close this window . . .

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" ]

printfn "Elements from Persons Set:"
for person in persons do
    printfn "Name: %s" person
    
printfn "------------------------------------"
printfn "Elements from Students Set:"
for std in students do
    printfn "Name: %s" std

printfn "------------------------------------"

let result = Set.isSubset students persons

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

It is important to know that the subset relationship goes 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:

Set

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:

Set

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

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

This function takes a Set value as argument and performs a comparison on its elements:

As an alternative to the Set.IsProperSubsetOf() function, 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() function.

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 function named IsSupersetOf. Its syntax is:

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

This function 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 function returns true. Here is an example:

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

printfn "Elements from Persons Set:"
for person in persons do
    printfn "Name: %s" person
    
printfn "------------------------------------"
printfn "Elements from Students Set:"
for std in students do
    printfn "Name: %s" std

printfn "------------------------------------"

let result = persons.IsSupersetOf students

printfn "Set Persons is a super set of set Student: %A " result

This would produce:

Elements from Persons Set:
Name: Daniel
Name: Jane
Name: Kevin
Name: Rebeccah
Name: Ruth
Name: William
------------------------------------
Elements from Students Set:
Name: Jane
Name: William
------------------------------------
Set Persons is a super set of set Student: true
Press any key to close this window . . .

As an alternative to the Set.IsSupersetOf() function, 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() function.

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() function 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 function named IsProperSupersetOf. Its syntax is:

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

This function works as follows:

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 for each type of collection. After creating the set from the other collection, all of the functions of the Set module 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

printfn "%A is a subset of %A: %A " setSomeEquares setNumbers sub

This would produce:

set [4; 16] is a subset of set [2; 4; 6; 8; 10; 12; 14; 16; 18; ...]: true
Press any key to close this window . . .

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

let intersection = Set.intersect setNames setMonths
printfn "Names"
printfn "__________________________________"
Set.iter (fun item -> printfn "Name: %s" item) intersection

This would produce:

Names
__________________________________
Name: April
Name: June
Press any key to close this window . . .

Previous Copyright © 2024, FunctionX Monday 04 September 2016 Next