nix-playgraound/notes/035-haskell-nonempty-waves.md

59 lines
1.4 KiB
Markdown
Raw Normal View History

# 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
```