A data transformation computes a new value or representation from existing data. Keeping that calculation separate from assigning or modifying state makes the relationship between input and result easier to see, test, and change. section 4.1.3
In F#, transformations commonly form pipelines: each expression produces a result that becomes the input to the next stage. This applies to individual values and to collections such as orders, customers, or match results. section 7.0 section 7.2.1
Finding the team with the most away wins
Filter match results to away wins, count wins by away team, then select the largest count. Each stage creates a new result rather than changing the original list, so another stage can be inserted without coupling it to the others. section 7.2.1
Listing 7.3 A declarative query implementation
let isAwayWin result = result.AwayGoals > result.HomeGoals
let wonAwayTheMost =
results
|> List.filter isAwayWin #1
|> List.countBy (fun result -> result.AwayTeam) #2
|> List.maxBy (fun (team, count) -> count) #3
This pipeline contrasts a focused sequence of filter, count, and maximum transformations with manual loops, mutable summaries, and state tracking. section 7.2.1
Use transformations to make collection work more direct:
- Prefer small functions with one transformation responsibility, then compose them into a larger pipeline. section 7.6
- Treat each pipeline stage as a result-producing expression rather than a statement that mutates shared data. section 7.2.1
- Run a subset of a pipeline in a script to inspect intermediate results step by step. section 7.6



















