liveBook · Manning

Pipeline

As explained in F# in Action: A Revised Edition of Get Programming with F#

A pipeline is a sequence of transformations in which the output of one step becomes the input of the next, applied here to HTTP requests and responses.

A pipeline is a left-to-right sequence of data transformations: each stage receives the previous stage’s output and produces the next value. This gives an application a simple shape—represent state as data, write functions that transform it, and compose those functions until reaching an effect such as returning JSON, writing a file, or sending an email. section 1.5.5

In F#, the forward-pipe operator, |>, makes that flow explicit. `value |> function` is equivalent to calling `function value`; for a curried function, the piped value supplies its last argument. Thus `10 |> add 5` means the same as `add 5 10`. A later stage can follow whenever its input type matches the preceding stage’s output type. section 6.1.3 section 6.4

Read transformations in execution order

Nested calls make the first transformation appear furthest right, while temporary variables manually carry each intermediate result. A pipeline keeps the data first and lists stages in the order they run: `10` `|> add 5` `|> add 7` `|> multiply 2` The multiline form is useful once stages have meaningful names or the chain grows beyond a single line. section 6.1.3

Figure 6.2 An example pipeline of functions

Follow the diagram as data moves through successive functions; the output arrow from one stage becomes the input to the next. section 6.1.3

Pipelines favor small, independently useful functions over a large routine that manages state between steps. For example, a customer identifier can flow through loading, review, email creation, and sending. Because stages need only agree on input and output shapes, a transformation can be inserted, replaced, or reused without requiring special pipeline declarations. section 6.1.3 section 7.6

Query a collection declaratively

A collection pipeline applies the same idea to a whole list. To find the team with the most away wins, filter match results, count them by away team, then choose the largest count: `results` `|> List.filter isAwayWin` `|> List.countBy (fun result -> result.AwayTeam)` `|> List.maxBy (fun (team, count) -> count)` Each stage returns a new result set rather than mutating a shared summary. This is shorter than nested loops and mutable bookkeeping, while making the requested transformations visible in order. 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

Inspect the three collection stages as a complete, concrete pipeline from match results to the winning away team. section 7.2.1

Long pipelines remain inspectable by running an initial subset in F# Interactive and observing its intermediate result. Editors can also show the inferred type at each stage, helping locate a broken connection when one function’s output cannot satisfy the next function’s input. Build and test a chain incrementally rather than treating it as one opaque expression. section 7.2.2

Figure 7.3 Executing a subset of a functional pipeline and observing the results

Use partial execution to see how a filter changes the data before continuing into later aggregation stages. section 7.2.2

The pattern extends beyond lists. It can process event streams, command input, files, database data, and transient domain data when they share a usable representation. In web work, the same functional style models an HTTP request/response pipeline, allowing composable F# handlers to run on ASP.NET Core. section 10.1.1 section 13.2

How F# in Action: A Revised Edition of Get Programming with F# covers it

How deep it goes
Explains forward-pipe syntax, curried arguments, collection stages, composability, and partial-execution debugging without implementation internals.
Examples
Demonstrates arithmetic chaining, customer-email processing, football-result aggregation, partial F# Interactive execution, timer events, and command-input sequences.
What it assumes
Introduces pipelines from ordinary function calls while relying on later familiarity with curried functions and collection operations.
What you can do after
Apply it with F# functions and collection modules to compose readable transformations and inspect intermediate results when connections fail.
How it connects
Connects currying, type inference, immutable lists, higher-order functions, declarative programming, sequences, events, and HTTP request/response handling.

Also explained in

Compare how 48 books explain pipeline →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of F# in Action: A Revised Edition of Get Programming with F#. The section links point to the parts of the book it draws on.