# Haskell NonEmpty Waves This note covers `32-haskell-nonempty-waves/`, which models rollout plans with `NonEmpty` so every plan is guaranteed to have at least one wave. --- ## 1. Why `NonEmpty` Matters A rollout plan with zero waves is not meaningful. Using `[Wave]` would force every caller to handle an impossible-but-representable empty case. This example makes that impossible state unrepresentable instead: ```haskell planWaves :: NonEmpty Wave ``` That means the rendering code can safely ask for the first and last wave without defensive checks. --- ## 2. What the Example Builds The example turns a release job into: - one wave for a rolling rollout, or - two waves for a canary rollout. Both cases still share the same output type. That is the real teaching point: `NonEmpty` lets you preserve list-like behavior while tightening the domain guarantee. --- ## 3. Why This Is Better Than a Runtime Check You could build a plain list and reject `[]` later. That would move the invariant into comments and runtime branches. `NonEmpty` pushes the guarantee into the type itself, which is more precise and easier to trust. --- ## 4. Commands to Try ```bash cd 32-haskell-nonempty-waves nix develop cabal run cabal run -- api:production:canary:20:6 cabal test nix build ./result/bin/mini-waves api:production:canary:20:6 nix run . -- api:production:canary:20:6 nix flake check ```