Chapter 12. Sequence expressions and alternative workflows

 

This chapter covers

  • Processing and generating sequences of values
  • Working with F# sequence expressions
  • Understanding monads and LINQ expressions
  • Implementing F# computation expressions

Before we can start talking about sequence expressions, you must know what a sequence is. This is another F# term that comes from mathematics, where a sequence is an ordered list containing a possibly infinite number of elements. Don’t worry if that all sounds a bit abstract; you’re already familiar with the type that expresses the same idea in .NET: IEnumerable<T>.

The primary reason for having the IEnumerable<T> type in the .NET Framework is it gives us a unified way to work with collections of data such as arrays, dictionaries, mutable lists, and immutable F# lists. In F# we’ll be talking about sequences, because this is a more general term. A sequence can represent a finite number of elements coming from a collection, but it can be also generated dynamically and retrieved on an on-demand basis. You’ll learn that infinite sequences, which sound somewhat academic, can still be useful in real applications.

12.1. Generating sequences

12.1.1. Using higher-order functions

12.1.2. Using iterators in C#

12.1.3. Using F# sequence expressions

12.2. Mastering sequence expressions

12.2.1. Recursive sequence expressions

12.2.2. Using infinite sequences

12.3. Processing sequences

12.3.1. Transforming sequences with iterators

12.3.2. Filtering and projection

12.3.3. Flattening projections

12.4. Introducing alternative workflows

12.4.1. Customizing query expressions

12.4.2. Customizing the F# language

12.5. First steps in custom computations

12.5.1. Declaring the computation type

12.5.2. Writing the computations

12.5.3. Implementing a computation builder in F#

12.5.4. Implementing query operators in C#

12.6. Implementing computation expressions for options

12.7. Augmenting computations with logging

12.7.1. Creating the logging computation

12.7.2. Creating the logging computation

12.7.3. Refactoring using computation expressions

12.8. Summary