1.7 KiB
Haskell Deriving Strategies
This note covers 24-haskell-deriving/, which uses deriving stock and GeneralizedNewtypeDeriving to build useful behavior for release-planning
types with very little manual code.
1. What the Example Derives
The example derives three kinds of behavior:
- ordering and display for enums and records,
- enumeration for the environment list, and
- numeric and semigroup behavior for newtypes.
Those derived instances are then used directly in the program:
allEnvironmentscomes fromEnumandBounded,sortedTargetsrelies on derivedOrd, andtotalFailureBudgetrelies on derivedNum.
2. Why the Constructor Order Matters
Derived ordering is not magical. It follows constructor order for sum types, and field order for product types.
That matters in this example:
PrioritylistsUrgentbeforeStandardandBackground, so urgent work sorts first, andReleaseTargetstores environment and priority before the service name, so the derived record ordering matches the intended rollout order.
This is the main teaching point: derived instances are only as good as the domain shape you give them.
3. Why the Newtypes Are Useful
BatchName and FailureBudget are wrappers, but they still need behavior.
GeneralizedNewtypeDeriving lets the example reuse the underlying instances:
BatchNamederivesSemigroupandMonoid, andFailureBudgetderivesNumandOrd.
That means the code can concatenate names and sum budgets without unpacking the wrappers everywhere.
4. Commands to Try
cd 24-haskell-deriving
nix develop
cabal run
cabal test
nix build
./result/bin/mini-deriving
nix run
nix flake check