HomeSearch

F# Seq Examples: Seq.sum, Seq.where

Use the Seq module and evaluate sequences with methods like sum and where.

Seq.

First comes 1, then 2, then 10. This is a sequence. In F# we use the Seq module on elements that are in IEnumerable collections. With seq we generate things as needed (lazily).

With helpful methods,

like sum, we count up the values of a collection. And Seq.where is more complex. It receives a Predicate, which we can specify with the fun keyword.

Sum example.

Here we introduce an int list. With Seq.sum we sum up the values in this collection. The sum of all the elements is 63. Notice how no for-loop is used.

Instead: The Seq.sum uses a declarative style of programming. It accepts one argument, the sequence we want to sum up.

F# program that uses Seq.sum let positions = [1; 2; 10; 20; 30] // Sum the elements in the list. let sum = Seq.sum positions printfn "%A" sum Output 63

Where.

Here we add some complexity. We use the where method. We first create a list of ints that go from 0 to 10 inclusive. This list has 11 elements in it.

Fun: We use the fun keyword to create a function that we pass to the where method. Our function receives one argument "b."

And: The fun returns true if the argument is greater than or equal to 5. So we get a list where all elements are at least 5.

F# program that uses Seq.where let positions = [0 .. 10] // Get elements that are greater than or equal to 5. let result = Seq.where (fun b -> (b >= 5)) positions printfn "%A" result Output seq [5; 6; 7; 8; ...]

Seq, yield.

This example uses a seq construct to create a lazily-evaluated sequence. We use a for-loop to create a series of numbers. We iterate over 10 past the start argument.

Yield: The yield keyword "returns" the number into the sequence during evaluation.

Lazy: Many of us are lazy. But for a seq, this is a useful feature: values are only generated as they are needed.

F# program that uses seq, yield // Compose doubledNumbers function with one argument. // ... The whitespace is important. let doubledNumbers start = seq { for start in start .. start + 10 do yield start } // Call the doubledNumbers function. let example = doubledNumbers 5 // Print the first few numbers of the sequence. printfn "%A" example // Print the entire sequence. for n in example do printfn "%A" n Output seq [5; 6; 7; 8; ...] 5 6 7 8 9 10 11 12 13 14 15

List comprehension.

We can omit the seq keyword when specifying a sequence comprehension. Inside square brackets, we specify a loop that yields the sequence's elements.

Tip: This is list comprehension. The sequence is evaluated and the type of the "odds" variable is "int list."

List

If not: We use an if-not statement to test that each number is not even. Logically this yields odd numbers.

If not
F# program that uses sequence comprehension, for loop // Use sequence comprehension to generate odd numbers. // ... Find odd numbers between 0 and 10 inclusive. let odds = [for number = 0 to 10 do if not (number % 2 = 0) then yield number] // Print results. printfn "%A" odds Output [1; 3; 5; 7; 9]

Distinct.

The Seq.distinct function removes duplicates from a list. This makes some code simpler. With Seq.distinctBy we can transform elements before making them distinct.Seq.distinct: remove duplicates

An indent issue.

When using seq blocks, we must be careful with indentation. It is usually a good idea to line up lines at the same indent level as the previous line.

Quote: Warning FS0058: Possible incorrect indentation: this token is offside of context started at position. Try indenting this token further or using standard formatting conventions (Visual Studio).

With Seq,

a module, we call functions on sequences like collections. We pass functions (lambda expressions) to some of the methods like where. This is powerful and expressive code.
Home
Dot Net Perls
© 2007-2019 Sam Allen. All rights reserved. Written by Sam Allen, info@dotnetperls.com.