5. Lists, arrays and sequences
Sections
Reading settings
No voice for this language in this browser.
More voices
Code and English terms
Off: the page’s voice reads everything, with no pause between two voices.
No voice for this language in this browser.
More voices
More voices: Microsoft Edge has natural online voices, and Windows (Settings › Time & language › Speech), macOS and Android install others.
C# has List<T>, arrays and IEnumerable<T>; Java has List<T>, arrays and Stream<T>. F# exposes the same trade-offs more explicitly through three collection families.
| F# type | Shape | Evaluation | Typical use |
|---|---|---|---|
'T list |
immutable linked list | eager | recursive algorithms, prepend-heavy transformations |
'T array |
mutable contiguous storage | eager | indexing, interop and performance-sensitive buffers |
seq<'T> |
IEnumerable<T> |
lazy | streaming or computed-on-demand pipelines |
Official references: List, Array and Seq.
One pipeline, three storage models
Section titled “One pipeline, three storage models”From l05_collections.fsx:
let openStrings = [ 40; 45; 50; 55; 59; 64 ]let upTwoFrets = openStrings |> List.map ((+) 2)
let mutablePitches = openStrings |> List.toArraymutablePitches[1] <- 46List.map returns a new list. Array item assignment uses <-, the same mutation operator introduced in lesson 2. Converting is explicit because the cost and mutability change.
Laziness is observable
Section titled “Laziness is observable”let mutable evaluated = 0let chromatic = seq { for pitch in 40 .. 44 do evaluated <- evaluated + 1 yield pitch }Measured output:
before Seq.take: 0first three: [40; 41; 42]after Seq.take: 3Creating a sequence executes nothing. Seq.take 3 |> Seq.toList pulls only three elements. Enumerating it again repeats the effects; use Seq.cache when repeated enumeration should reuse values, or materialize with Seq.toArray/Seq.toList when the input is finite.
Transform, filter, choose, fold
Section titled “Transform, filter, choose, fold”mapchanges every element.filterkeeps elements satisfying a predicate.choosecombinesOption-producing mapping with filtering.foldcarries explicit state from left to right.collectmaps each input to a collection and flattens once.
let playedFrets = [ Some 0; None; Some 7; Some 9 ]let played = playedFrets |> List.choose id// [0; 7; 9]Prefer the module matching the concrete collection (List.map, Array.map). Seq.map accepts every IEnumerable<T>, but it also makes an eager source lazy and can hide repeated work.
Exercise
Section titled “Exercise”Given six optional fret positions, produce the sounding MIDI pitches while preserving string order. Use List.choose, not mutable accumulation. Then rewrite it as a lazy sequence and state when it is evaluated.
Continue with modules and project organization.