# F# Sequences

In this article, we will take a closer look at **F# sequences** and how they can be used with examples.

**F# Sequences** is a data abstraction over a collection, and it allows for efficient, lazy evaluation and composition of data, allowing it to provide fast and efficient access to the data.

## Creating F# Sequences

This syntax is used to define sequences in the following way:

seq { expr } For example, let seq1 = seq { 1 .. 8 }

Sequences can also be created using ranges and comprehensions, similar to lists.

A sequence expression is an expression which you can use to create sequences from the input data.

You can do these things:

- This can be done by specifying a range of values.
- This can be done by specifying a range along with increments or decrements.
- It is done by using a keyword called yield to produce values that will become part of a sequence after being executed.
- You can do this by using the ‘
**→**‘ operator.

## F# Sequences Basic Example

Here is the simple example to understand the concept of sequence:

#### Example:

And the output will be:

The Sequence: seq [1; 2; 3; 4; ...] The Sequence: seq [1; 3; 5; 7; ...] The Sequence: seq [20; 18; 16; 14; ...] The Sequence: seq [(1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64); ...]

## Prime Number Checker

To check the numbers are prime or not in the sequence:

#### Example:

The above program results as follows:

1 2 3 5 7 11 13 17 19

## F# Sequence Operations

Here is a table showing the basic operations that can be performed on a sequence data type:

Value | Overview |

append : seq<‘T> → seq<‘T> → seq<‘T> | The function returns a new sequence containing the elements of the first sequence followed by the elements of the second sequence at the end. |

average : seq<^T> → ^T | The average element in the sequence of elements is returned as the result of this function. |

averageBy : (‘T → ^U) → seq<‘T> → ^U | By applying the function to each element of the sequence and taking the average of both elements, it will return the average of the elements generated. |

cache : seq<‘T> → seq<‘T> | This method returns a sequence of sequences that correspond to a cached version of the input sequence that has been input. |

cast : IEnumerable → seq<‘T> | Provides a way to wrap loosely-typed systems. The sequence of collections is typed as a sequence of collections. |

choose : (‘T → ‘U option) → seq<‘T> → seq<‘U> | The given function will be applied to every element of the sequence one by one. This function will return a sequence of each element’s result for each element where the function returns Some as a result. |

collect : (‘T → ‘Collection) → seq<‘T> → seq<‘U> | This function will be applied to each element of the sequence , one at a time. Return the combined sequence of all the results after concatenating all of them together. |

compareWith : (‘T → ‘T → int) → seq<‘T> → seq<‘T> → int | The function compares two sequences, element by element, using the comparison function that has been given. |

concat : seq<‘Collection> → seq<‘T> | A new sequence will be returned which will contain the elements of all of the sequences , sorted alphabetically. |

countBy : (‘T → ‘Key) → seq<‘T> → seq<‘Key * int> | This function generates unique keys for each element of a sequence and returns the number of instances of those keys in the original sequence. |

delay : (unit → seq<‘T>) → seq<‘T> | Returns a sequence that is created from a sequence specification that has been delayed and the configuration that has been given. |

distinct : seq<‘T> → seq<‘T> | In this method, the entries are hashed and the equality of the entries is compared to determine whether they are duplicates. The later occurrences of an element are discarded if the element occurs more than once in the sequence. |

distinctBy : (‘T → ‘Key) → seq<‘T> → seq<‘T> | Based on the general hashing and equality comparison of the keys returned by the key-generating function, this function returns a sequence of entries that do not contain any duplicate entries. When the same element occurs in a sequence multiple times, then the later occurrence of the element is discarded. |

empty : seq<‘T> | The function returns an empty sequence with the given type as its value. |

exactlyOne : seq<‘T> → ‘T | The empty sequence is created as a result of this function. |

exists : (‘T → bool) → seq<‘T> → bool | The function checks if any element from the sequence meets the given predicate by checking whether it is present. |

exists2 : (‘T1 → ‘T2 → bool) → seq<‘T1> → seq<‘T2> → bool | In this function, it is tested to see if a pair of corresponding elements in the sequences is satisfied by the given predicate. |

filter : (‘T → bool) → seq<‘T> → seq<‘T> | In this function, a new collection is returned that contains only those elements of the original collection for which the given predicate corresponds to true. |

find : (‘T → bool) → seq<‘T> → ‘T | It returns the element that is the first element to return true when the given function is used. |

findIndex : (‘T → bool) → seq<‘T> → int | A predicate that is satisfied by the first element in the sequence is returned. |

fold : (‘State → ‘T → ‘State) → ‘State → seq<‘T> → ‘State | This function threads an accumulator argument through each element of the collection. It applies the function to the second argument and the first element of the sequence . This result will then be passed by the program along with the second element, and the process will continue in this way. It then returns the final result. A function f is given, and the elements are i0…iN, so this function computes f (… (f s i0) i1 …) iN. |

forall : (‘T → bool) → seq<‘T> → bool | This function is used to determine whether or not all elements of the sequence meet the given predicate. |

forall2 : (‘T1 → ‘T2 → bool) → seq<‘T1> → seq<‘T2> → bool | The purpose of the test is to see whether all pairs of elements that are drawn from either sequence satisfy the given predicate. The remaining elements of the sequence will be ignored if one of the sequence lengths is shorter than the other. |

groupBy : (‘T → ‘Key) → seq<‘T> → seq<‘Key * seq<‘T>> | Each element of a sequence is applied to a key-generating function, which yields a sequence of unique keys based on the elements of that sequence. In addition to a unique key, there is also a sequence containing all elements that match the unique key in order to make it unique. |

head : seq<‘T> → ‘T | It is used to return the first element in a sequence . |

init : int → (int → ‘T) → seq<‘T> | The function creates a sequence by using the given generator as an index on each item in the sequence . |

initInfinite : (int → ‘T) → seq<‘T> | The function returns successive elements when iterated, based on the newly created sequence. A call to the function does not save its results, which means that the function will have to be applied again to regenerate the elements in the future. Using the index, the function can generate an item. |

isEmpty : seq<‘T> → bool | This method returns true if the sequence does not contain any elements, and false if it does. |

iter : (‘T → unit) → seq<‘T> → unit | Every element in the sequence will be applied with the given function. |

iter2 : (‘T1 → ‘T2 → unit) → seq<‘T1> → seq<‘T2> → unit | The given function is applied simultaneously to two sequences. There must be an identical size between the two sequences. |

iteri : (int → ‘T → unit) → seq<‘T> → unit | Each element in the sequence is applied to the given function. Integers passed to the function indicate element indexes. |

last : seq<‘T> → ‘T | The last element of the sequence is returned when this function is called. |

length : seq<‘T> → int | The length of the sequence is returned by this function. |

map : (‘T → ‘U) → seq<‘T> → seq<‘U> | In this method, the elements of a collection are the results of applying a given function to each element of a collection, and the result is returned as the elements of a new collection. |

map2 : (‘T1 → ‘T2 → ‘U) → seq<‘T1> → seq<‘T2> → seq<‘U> | In this method, a new collection is created whose elements correspond to the respective elements of the two sets of collections if the given function is applied pairwise to the corresponding elements of the two sets. |

mapi : (int → ‘T → ‘U) → seq<‘T> → seq<‘U> | Applying a given function to each element of the collection creates a new collection whose elements are the results of the application. This integer index represents the element’s index (from 0) when passed to the function. |

max : seq<‘T> → ‘T | By using Operators.max, this function returns the greatest value among all of the elements in the sequence. |

maxBy : (‘T → ‘U) → seq<‘T> → ‘T | The function returns the greatest element in the sequence among all the elements of the sequence, comparing the result of the function with its Operators.max method. |

min : seq<‘T> → ‘T | This function returns the lowest element in a sequence, compared using Operators.min as a comparison method. |

minBy : (‘T → ‘U) → seq<‘T> → ‘T | Using Operators.min on the result of the function, this function returns the lowest element within all the elements of the sequence. |

nth : int → seq<‘T> → ‘T | The index of each item in the sequence. 0 is the index of the first element in the sequence. |

ofArray : ‘T array → seq<‘T> | Provides a sequence view of the given array. |

ofList : ‘T list → seq<‘T> | Provides a sequence view of the given list. |

pairwise : seq<‘T> → seq<‘T * ‘T> | This function returns a sequence that contains the number of elements in the input sequence along with the number of the elements’ predecessors, except that the first element is only returned as the predecessor of the second element in the sequence. |

pick : (‘T → ‘U option) → seq<‘T> → ‘U | This function is applied to successive elements, returning the first value returned by the function where a value of Some is returned by the function. |

readonly : seq<‘T> → seq<‘T> | In this method the sequence object is created from the given sequence object and delegated to it. The purpose of typecasting is to prevent the original sequence from being discovered and mutated again by a typecast. As an example, if you are given an array of elements to produce a sequence, you will receive the elements from the array, but you cannot cast the sequence object back to an array of elements. |

reduce : (‘T → ‘T → ‘T) → seq<‘T> → ‘T | Each element of the sequence is applied with a function and an accumulator argument is threaded through the calculation to bring about the output. The first two elements should be applied with the function in the beginning. You then need to feed this result along with the third element in the function and so on. The final result should be returned. |

scan : (‘State → ‘T → ‘State) → ‘State → seq<‘T> → seq<‘State> | This method is similar to Seq.fold, however it computes on-demand and returns the sequence of intermediate and final results as a result. |

singleton : ‘T → seq<‘T> | This method returns a sequence with only one item in it. |

skip : int → seq<‘T> → seq<‘T> | During the generation of the returned sequence, the user can specify the number of elements that should be skipped from the underlying sequence, followed by a yield of the remaining elements from the sequence. |

skipWhile : (‘T → bool) → seq<‘T> → seq<‘T> | If the given predicate returns true, then a sequence will be returned which skips elements of the underlying sequence in order to produce the remaining elements while the given predicate returns true. |

sort : seq<‘T> → seq<‘T> | By using Operators.compare, this function sorts the sequence given to it. |

sortBy : (‘T → ‘Key) → seq<‘T> → seq<‘T> | The given sequence is sorted using the keys provided by the projection given in the input. Using the Operators.compare method, keys are compared between each other. |

sum : seq<^T> → ^T | This function sums up all elements and returns an integer. |

sumBy | The function gives back a sum of the results generated by applying the function to each element of a sequence in order to generate the results. |

take : int → seq<‘T> → seq<‘T> | The function returns the first element in a sequence up until a certain count has been specified. |

takeWhile : (‘T → bool) → seq<‘T> → seq<‘T> | A sequence in this function returns elements from the underlying sequence when iterated some number of times while returning true if the given predicate is true, and no further elements when the given predicate is false. |

toArray : seq<‘T> → ‘T[] | From a collection of items, this function creates an array. |

toList : seq<‘T> → ‘T list | From a given collection, this function will create a list. |

truncate : int → seq<‘T> → seq<‘T> | When enumerated, this function gives a sequence with a maximum number of elements to return when it is enumerated. |

tryFind : (‘T → bool) → seq<‘T> → ‘T option | This function returns the first element, or None if no such element exists, which is returned by the given function. |

tryFindIndex : (‘T → bool) → seq<‘T> → int option | The index is returned if the given predicate is satisfied at the onset of the sequence, otherwise if the predicate is not satisfied at onset of the sequence, then None is returned. |

tryPick : (‘T → ‘U option) → seq<‘T> → ‘U option | This function is applied to successive elements, returning the first value returned by the function where a value of some is returned by the function. |

unfold : (‘State → ‘T * ‘State option) → ‘State → seq<‘T> | This method returns a sequence containing the elements that would be generated by the given computation, if one is provided. |

where : (‘T → bool) → seq<‘T> → seq<‘T> | In order to return a new collection, you must specify a predicate that returns true for all elements found in the previous collection. Seq.filter is a synonym. |

windowed : int → seq<‘T> → seq<‘T []> | The function returns a sequence which produces sliding windows of elements which contain elements drawn from the sequence input. There is a fresh array returned for each window. |

zip : seq<‘T1> → seq<‘T2> → seq<‘T1 * ‘T2> | A list of pairs is formed by combining two sequences. If one sequence has exhausted all elements, the other sequence is ignored and no further elements are added to the other sequence. This is despite the two sequences not having equal lengths. |

zip3 : seq<‘T1> → seq<‘T2> → seq<‘T3> → seq<‘T1 * ‘T2 * ‘T3> | A list of triples is formed by combining three sequences. If one sequence has exhausted all elements, the other sequence is ignored and no further elements are added to the other sequence. This is despite the three sequences not having equal lengths. |

#### Example:

The singleton sequence:seq [12] The init sequence: 0 2 4 6 8 10 12 14 The array sequence 1: 1 2 3 4 5 6 7 8 The array sequence 2: 1 3 5 7 9 11 13 15 17 19

The following points need to be noted:

- The method
**Seq.empty**creates an empty sequence when it is called. - In the
**Seq.singleton**method, only one element of a sequence is created by specifying its name. - The method
**Seq.init**creates a sequence of elements within which a function is passed in order to create the elements. - The
**Seq.ofArray**and**Seq.ofList<‘T>**methods are used to create sequences from arrays and lists of elements. - In the
**Seq.iter**method, you can iterate through a sequence by iterating through it.

## Sum and Average Calculation

Calculating the sum and average of all elements in sequence:

#### Example:

## F# Sequence Seq.unfold

Using the** Seq.unfold** method, you can create a sequence from a state that is transformable so that each element in the sequence can be created using that state.

This is done by transforming the state before going on with the computation.

Here are the first 30 natural numbers produced by the Seq.unfold method:

#### Example:

And the result of the above example is:

The sequence seq1 contains numbers from 0 to 30. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,

## Array Conversion to Sequence and Sorting

Below is an example of creating an array and then converting it into a sequence, as well as sorting the sequence.

#### Example:

## Seq.truncate & Seq.take

This method, **Seq.truncate**, creates a new sequence from another sequence, but restricts the next element in the new sequence to a specified number.

With the **Seq.take** method, a new sequence is created which begins with precisely a specified number of elements and contains them starting from the beginning of the sequence.

#### Example:

The output will be:

The original: 2 4 6 8 10 12 14 16 18 20 The truncated: 2 4 6 8 10 The take: 2 4 6 8

### Example Explanation

Above example demonstrates the use of the **Seq.truncate** and **Seq.take** functions in F# to obtain subsequences from a sequence.

First, we define a sequence using a sequence expression that generates the values **2, 4, 6, 8, 10, 12, 14, 16, 18, 20**.

Then, we use Seq.truncate to truncate the sequence to the first 5 elements and store the result in truncate. We also use Seq.take to take the first 4 elements of the sequence and store the result in.

Finally, we use Seq.iter to print out the original sequence and the two subsequences. The** Seq.iter** function applies a function to each element of a sequence, and in this case, we use it to print out the elements of the sequence.

Note that Seq.truncate returns a new sequence with the specified number of elements from the beginning of the original sequence. If the original sequence has fewer elements than the specified number, the entire sequence is returned.

Similarly, Seq.take returns a new sequence with the specified number of elements from the beginning of the original sequence. If the original sequence has fewer elements than the specified number, only the available elements are returned.