← All examples
28

Canonical Grid model

Algebraic Choice Lifecycle

Payload-bearing CHOICE types: constructors, exhaustive constructor-pattern MATCH, guards, and a finite recursive value.

Scale
Medium
Source
28-choice-adts.grid
Length
80 lines
Collection
Advanced language
Level
Advanced
Runtime
Portable
Version
1.0.0

Watch it in Grid

See this model in motion.

Watch the model respond in the product, then inspect the exact source and checkpoints on this page.

Companion film

Name the logic. Close the state.

Change one order total and watch a named pricing function and a closed Order choice update the decision while the ledger stays intact.

49 secGrid 0.63.2
Open film page

What this model gives you

A closed order lifecycle with payload constructors, exhaustive matching, guards, and a finite recursive approval chain.

20 min to study · Source reviewed 2026-08-25

Continue with guided practice

What to notice

  • Payload-bearing CHOICE types
  • Exhaustive constructor matching
  • Guarded arms and payload extraction
  • Finite recursive values

Requirements

  • Portable
  • No connector
  • No network

Expected checkpoint

A known state for this walkthrough.

After constructing the canonical order states and two-hop approval escalation.

Shipment
shipped 3dB1
Pick policy
priority-pickB2
Shipped total
2,620B3
Approval
finance-chief / 2 hopsD1 / D2
01 · Close

Constructors define every valid lifecycle state

Draft, placed, shipped, and cancelled values carry only their declared payloads.

02 · Match

Exhaustiveness makes change visible

Every constructor has an unguarded path while guards refine policy inside one case.

03 · Recurse

Recursive data remains finite and inspectable

Nested escalation constructors retain the complete approval path without an unbounded evaluator.

28-choice-adts.grid
Get Grid
MODEL "Algebraic Choice Lifecycle"
DESCRIPTION "Payload-bearing CHOICE types: constructors, exhaustive constructor-pattern MATCH, guards, and a finite recursive value."
VERSION "1.0.0"
AUTHOR "Grid Team"
TAGS "canonical", "choice", "adt", "match", "recursion"

# A closed order lifecycle with payload-bearing constructors
CHOICE Order =
  Draft |
  Placed(total: number) |
  Shipped(total: number, transit_days: number) |
  Cancelled(reason: string)

# Constructed values are immutable and contract-checked at build time
A1 = Order.Placed(1840)
A2 = Order.Shipped(2620, 3)
A3 = Order.Cancelled("payment declined")
A4 = Order.Draft()

# Exhaustive matching: every constructor needs an unguarded arm
B1 = MATCH(
  A2,
  Order.Draft() -> "draft",
  Order.Placed(total) -> "placed " & TEXT(total, "0"),
  Order.Shipped(total, transit_days) -> "shipped " & TEXT(transit_days, "0") & "d",
  Order.Cancelled(reason) -> "cancelled: " & reason
)

# Guards test payload values; the unguarded arms keep the match exhaustive
B2 = MATCH(
  A1,
  Order.Placed(total) IF total > 1500 -> "priority-pick",
  Order.Placed(_) -> "standard-pick",
  Order.Shipped(_, _) -> "in-transit",
  _ -> "no-pick"
)

# Payload extraction with ignored fields
B3 = MATCH(
  A2,
  Order.Shipped(total, _) -> total,
  _ -> 0
)

# A finite recursive value: an escalation chain stored as data
CHOICE Approval =
  Granted(approver: string) |
  Escalated(role: string, remainder: Approval)

C1 = Approval.Escalated("team-lead", Approval.Escalated("director", Approval.Granted("finance-chief")))

# Fold the chain with nested matches; recursive values stay finite (depth <= 64)
D1 = MATCH(
  C1,
  Approval.Granted(approver) -> approver,
  Approval.Escalated(role, rest) -> MATCH(
    rest,
    Approval.Granted(mid_approver) -> mid_approver,
    Approval.Escalated(mid_role, deeper) -> MATCH(
      deeper,
      Approval.Granted(top_approver) -> top_approver,
      _ -> "still-escalating"
    )
  )
)

D2 = MATCH(
  C1,
  Approval.Granted(_) -> 0,
  Approval.Escalated(_, rest) -> 1 + MATCH(
    rest,
    Approval.Granted(_) -> 0,
    Approval.Escalated(_, deeper) -> 1 + MATCH(deeper, Approval.Granted(_) -> 0, _ -> 1)
  )
)

# Summary
E1 = `final_approver={D1} escalation_hops={D2} pick={B2}`

END MODEL