jonnifyfsharp

Module C1.06

Discriminated unions & records

Two type-builders — and with them a domain modelled so precisely the wrong value will not compile.

The previous module read data by its shape. This one builds the shapes. F# has two algebraic type-builders. A record is a product type: a value has field A and field B and field C — a Point is an X together with a Y. A discriminated union is a sum type: a value is case A or case B or case C — a Shape is a Circle or a Rectangle, never both. Compose the two and the set of values a type admits matches the set of values the domain allows, so an illegal state cannot be constructed — the third dive makes that its lesson. These are the types the next module's collections hold, and the ones Option and Result are themselves built from.

Sum and product, in three dives

Two builders cover the algebra of data. Product combines fields with and; the number of values a product admits is the product of its fields' value counts. Sum combines cases with or; the number of values a sum admits is the sum of its cases' value counts. Choosing the builder that matches the domain is the whole craft — and it is what makes the bad value impossible to write. Select a dive below to read its summary and the one idea it adds.

The first dive builds records — declared by their field names, immutable, compared by their contents, copied-and-updated to a new value. The second builds discriminated unions — a closed set of cases, each optionally carrying data, exhaustively handled by a match. The third is the payoff: making illegal states unrepresentable, where a union that lists only the legal combinations turns a domain rule into a compile-time guarantee.

The three dives · select one

C1.06.1 records C1.06.2 discriminated unions C1.06.3 illegal states product · and sum · or the payoff
C1.06.1 · Records

A product type: a value has every field at once. Declared by its field names, immutable, compared by contents, and copied-and-updated to a new record with { p with Y = 3.0 }.

You learn how to declare, build, and copy-update a record

Open this dive · or pick another above

And-types hold every field; or-types hold one case. Compose them and the type admits exactly the values the domain allows — no more, no fewer.

The three dives

Read them in order. Each stands on valid, runnable F#: every type declaration, every constructed value, and every FSI line below can be typed into dotnet fsi and produces exactly what the page shows.

live module hub built dive ready soon specified

References

Sources

Related in this course