F# - Sequences

Sequences, like lists also represent an ordered collection of values. However, the elements in a sequence or sequence expression are computed when required. They are not computed at once, and for this reason they are used to represent infinite data structures.
Sequences are defined using the following syntax −
seq { expr }

For example,
let seq1 = seq { 1 .. 10 }

Similar to lists, you can create sequences using ranges and comprehensions.
Sequence expressions are the expressions you can write for creating sequences. These can be done −
By specifying the range.
By specifying the range with increment or decrement.
By using the yield keyword to produce values that become part of the sequence.
By using the → operator.
The following examples demonstrate the concept −
(* Sequences *)
let seq1 = seq { 1 .. 10 }

(* ascending order and increment*)
printfn "The Sequence: %A" seq1
let seq2 = seq { 1 .. 5 .. 50 }

(* descending order and decrement*)
printfn "The Sequence: %A" seq2

let seq3 = seq {50 .. -5 .. 0}
printfn "The Sequence: %A" seq3

(* using yield *)
let seq4 = seq { for a in 1 .. 10 do yield a, a*a, a*a*a }
printfn "The Sequence: %A" seq4
When you compile and execute the program, it yields the following output −
The Sequence: seq [1; 2; 3; 4; ...]
The Sequence: seq [1; 6; 11; 16; ...]
The Sequence: seq [50; 45; 40; 35; ...]
The Sequence: seq [(1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64); ...]

The following program prints the prime numbers from 1 to 50 −
(* Recursive isprime function. *)
let isprime n =
   let rec check i =
      i > n/2 || (n % i <> 0 && check (i + 1))
   check 2

let primeIn50 = seq { for n in 1..50 do if isprime n then yield n }
for x in primeIn50 do
   printfn "%d" x
When you compile and execute the program, it yields the following output −
1
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47

The following table shows the basic operations on sequence data type −
The following examples demonstrate the uses of some of the above functionalities −
This program creates an empty sequence and fills it up later −
(* Creating sequences *)
let emptySeq = Seq.empty
let seq1 = Seq.singleton 20

printfn"The singleton sequence:"
printfn "%A " seq1
printfn"The init sequence:"

let seq2 = Seq.init 5 (fun n -> n * 3)
Seq.iter (fun i -> printf "%d " i) seq2
printfn""

(* converting an array to sequence by using cast *)
printfn"The array sequence 1:"
let seq3 = [| 1 .. 10 |] :> seq<int>
Seq.iter (fun i -> printf "%d " i) seq3
printfn""

(* converting an array to sequence by using Seq.ofArray *)
printfn"The array sequence 2:"
let seq4 = [| 2..2.. 20 |] |> Seq.ofArray
Seq.iter (fun i -> printf "%d " i) seq4
printfn""
When you compile and execute the program, it yields the following output −
The singleton sequence:
seq [20]
The init sequence:
0 3 6 9 12
The array sequence 1:
1 2 3 4 5 6 7 8 9 10
The array sequence 2:
2 4 6 8 10 12 14 16 18 20

Please note that −
The Seq.empty method creates an empty sequence.
The Seq.empty method creates an empty sequence.
The Seq.singleton method creates a sequence of just one specified element.
The Seq.singleton method creates a sequence of just one specified element.
The Seq.init method creates a sequence for which the elements are created by using a given function.
The Seq.init method creates a sequence for which the elements are created by using a given function.
The Seq.ofArray and Seq.ofList<'T> methods create sequences from arrays and lists.
The Seq.ofArray and Seq.ofList<'T> methods create sequences from arrays and lists.
The Seq.iter method allows iterating through a sequence.
The Seq.iter method allows iterating through a sequence.
The Seq.unfold method generates a sequence from a computation function that takes a state and transforms it to produce each subsequent element in the sequence.
The following function produces the first 20 natural numbers −
let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20."
for x in seq1 do printf "%d " x
printfn" "
When you compile and execute the program, it yields the following output −
The sequence seq1 contains numbers from 0 to 20.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

The Seq.truncate method creates a sequence from another sequence, but limits the sequence to a specified number of elements.
The Seq.take method creates a new sequence that contains a specified number of elements from the start of a sequence.
let mySeq = seq { for i in 1 .. 10 -> 3*i }
let truncatedSeq = Seq.truncate 5 mySeq
let takeSeq = Seq.take 5 mySeq

printfn"The original sequence"
Seq.iter (fun i -> printf "%d " i) mySeq
printfn""

printfn"The truncated sequence"
Seq.iter (fun i -> printf "%d " i) truncatedSeq
printfn""

printfn"The take sequence"
Seq.iter (fun i -> printf "%d " i) takeSeq
printfn""
When you compile and execute the program, it yields the following output −
The original sequence
3 6 9 12 15 18 21 24 27 30
The truncated sequence
3 6 9 12 15
The take sequence
3 6 9 12 15

 Print
 Add Notes
 Bookmark this page