Part 10: Sum types

A setting in a configuration file is a number, a switch or a word. A token from a tokenizer is a number, a name or an operator. Rux writes "one of these types" directly in the type: int32 | bool | char8[..]. The value always knows which member it holds, and the compiler will not let you treat it as any one of them until you have asked. This part shows how to build such a value, how to ask, and how sums of different sizes fit together.

What you will learn

  • What A | B means, and why it is a set of types: order and duplicates make no difference, and int32 | int32 is plain int32.
  • How a value goes into a sum, and when a literal is ambiguous.
  • Matching a sum by the type it holds with a typed pattern, n: int32 =>, and covering every member.
  • Handling several members in one arm with a subset pattern, box: Square | Rectangle =>, and passing the smaller sum on.
  • Asking which member is active with is, which answers with a bool and never unpacks anything.
  • Widening: a smaller sum fits wherever a larger one is expected, but never the other way round.

Into a sum and back out

flowchart LR
    m["A member value<br/>Square { side: 2.0 }"] -- "goes in" --> s(["Circle | Square | Rectangle"])
    small["A smaller sum<br/>Square | Rectangle"] -- "widening" --> s
    s --> t["typed pattern<br/>s: Square =>"]
    s --> sub["subset pattern<br/>box: Square | Rectangle =>"]
    s --> is["is<br/>shape is Circle"]
    t --> t2["one member,<br/>as its own type"]
    sub --> sub2["a smaller sum"]
    is --> is2["a bool, nothing unpacked"]
You want to…UseLesson
use the value insidematch with n: int32 =>Typed pattern
handle several members alikematch with box: Square | Rectangle =>Subset pattern
only know which member it isvalue is T, value is (A | B)The is operator
pass a smaller sum to a larger parameternothing — it widens by itselfSum widening

Lessons

LessonWhat you will learn
10.1Sum typea value that can be an int32 or a bool: int32 | bool
10.2Typed patternmatch a sum by the type it holds
10.3Subset patternmatch several members of a sum in one arm
10.4The is operatorask which type a sum holds with is
10.5Sum wideningpass a smaller sum where a larger one is expected

Before you start

Finish Parts 1–9 first. This part leans on Type alias, Variant and Variant match from Part 6 — a sum is matched much as a variant is — and on Error sum from Part 9, where you first wrote A | B as a function's error type. Each lesson's package is in the Examples repository's SumTypes/ folder:

cd Examples/SumTypes/SumType
rux run

After this part

Part 11: Ownership turns from what a value is to who owns it — copies, moves, destructors and defer. Sums come back in Part 13: Generics, where Generic sum builds T | U from type parameters and the "a sum is a set" rule decides what T | U becomes when T and U are the same type. The next checkpoint projects, Circle and Quadratic, come after Part 16.

For the rules behind this part, see match, Type tests and Type aliases in the Rux Reference.