Skip to main content

Enums / Tagged Unions

Enums in Mux are tagged unions (also called algebraic data types or sum types) that can hold different variants with associated data.

Basic Enum Definition

basic_enum.mux
Loading...

Key Points:

  • Each variant is a case of the enum
  • Variants can carry associated data (or none)
  • Every payload field is named, like a function parameter: Circle(float radius)

Creating Enum Instances

A variant is always reached through the enum name, and parentheses mean arguments. A variant with no payload takes none; writing () anyway is an error, not an accepted alias.

creating_enums.mux
Loading...

Three things are rejected, each with a suggestion:

Mux
Loading...

A variant is also not reachable through a value of the enum - myShape.Circle is an error suggesting match instead.

Pattern Matching with Enums

Use match to handle different enum variants:

pattern_matching_enums.mux
Loading...

Ignoring Associated Data

Use _ to ignore data you don't need:

ignoring_enum_data.mux
Loading...

Pattern Matching with Guards

Add conditional logic with guards:

enum_guards.mux
Loading...

Arms are tried in order, so the guarded arms have to come before the bare one - Some(v) with no guard matches everything the guarded arms would have.

Generic Enums

An enum can be generic over type parameters. Each instantiation is monomorphized - Box<int> gets its own layout holding a real int, not a boxed pointer - so there is no cost to reaching for one.

enum_generics.mux
Loading...

The type argument has to be concrete at the point of use: Box<int>.Full(42), not Box.Full(42).

optional and result are built in and are not user enums - you cannot declare your own type named optional or result, and you construct them with some, none, ok and err rather than through an enum name. See optional Values below.

Comparing Enums

Enums compare structurally with == and !=: same variant, and equal payloads. The comparison recurses, so nested and recursive enums compare all the way down. This is the same comparison that lets an enum be a map key or a set member.

comparing_enums.mux
Loading...

optional and result compare the same way. There is no ordering for enums - < is not defined on them.

Enums Have No to_string()

Color.Red.to_string() is an error, and deliberately so: only you know whether HTTPCode.Ok should render as "Ok" or as "200". Write the conversion as a function and call it:

enum_display.mux
Loading...

Exhaustiveness checking makes this safe to extend: adding a variant turns every such function into a compile error listing what is missing, rather than a silently wrong default.

Common Enum Patterns

optional Values

optional_values.mux
Loading...

result Types for Error Handling

result_types.mux
Loading...

See Error Handling for more details on result and optional.

State Machines

state_machines.mux
Loading...

Nested Enums

nested_enums.mux
Loading...

Enums in Collections

enums_in_collections.mux
Loading...

Exhaustiveness Checking

Mux enforces exhaustive pattern matching - all variants must be covered:

exhaustiveness_checking.mux
Loading...

Best Practices

  1. Use enums for mutually exclusive states - Better than multiple booleans
  2. Match exhaustively - Don't overuse wildcard patterns
  3. Use guards for additional logic - Cleaner than nested if statements
  4. Ignore unused data with _ - Makes intent explicit
  5. Prefer result over exceptions - Explicit error handling
  6. Prefer optional over null - No null pointer errors
  7. Use generic enums for reusable patterns - Option<T>, result<T, E>

See Also