liveBook · Manning

Composition

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

Function composition is the operation of combining functions so that the output of one function becomes the input of another.

Function composition combines functions into a new function: the output of the first becomes the input of the second. In F#, `>>` composes two functions when their input and output types line up. This supports a reuse style built from small, focused functions rather than tightly coupled, stateful sets of methods. section 2.1.2 section 6.1.3

Composition is useful when a transformation has a stable shape that can be named and reused. For example, filtering a sequence to even numbers and then squaring the results can become one composed behavior. The component functions remain easy to inspect or change independently, while the combined function expresses the larger operation directly. section 2.1.2

Distinguish two related ways to connect functions:

  • Use `>>` to create a new function from two existing functions. `add 5 >> multiply 2` creates a function that adds five and then doubles its input. section 6.1.3
  • Use `|>` to send an existing value through a visible sequence of calls. It avoids manually naming intermediate values or nesting calls when the operations form a logical flow. section 6.1.3
  • Avoid treating pipelines as mandatory syntax. They work best when the threaded data and order of operations are clearer than a direct function call. section 6.1.3

Build a reusable transformation

A manually threaded calculation can first add 5, then add 7, then multiply by 2. A pipeline makes the data flow explicit: `10 |> add 5 |> add 7 |> multiply 2`. When the intention is to define the operation itself rather than immediately run it, composition is shorter: `let addFiveAndDouble = add 5 >> multiply 2`. Both forms preserve the same sequence; the choice depends on whether the focus is the value flowing now or a function to use later. section 6.1.3

let addFiveAndDouble input = input |> add 5 |> multiply 2
let addFiveAndDoubleShort = add 5 >> multiply 2

Compare a pipeline-defined transformation with its `>>` equivalent: both add five and then multiply by two, but only `>>` directly constructs the reusable function from its parts. section 6.1.3

Composition also scales beyond data transformations. Giraffe chains HTTP handlers with its `>=>` operator, an alias for `compose`: `GET >=> route "/device/status" >=> text "device is operating correctly"` creates one handler from method, route, and response handlers. At higher application levels, composed functions often orchestrate calls, so integration tests can validate complete business scenarios, including paths that use an actual database. section 13.2.3 section 14.3.4

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

How deep it goes
Defines `>>`, contrasts it with pipelines, and treats composition as shorthand rather than explaining implementation internals.
Examples
Uses number transformations, an email workflow, a gas-state exercise, and a GET `/device/status` handler.
What you can do after
Apply it via F# and Giraffe to chain transformations or HTTP handlers into readable workflows.
How it connects
Connects composition to pipelines, HTTP handlers, and integration testing.

Also explained in

Compare how 11 books explain composition →

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.