65 lines
1.7 KiB
Markdown
65 lines
1.7 KiB
Markdown
|
|
# 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:
|
||
|
|
|
||
|
|
- `allEnvironments` comes from `Enum` and `Bounded`,
|
||
|
|
- `sortedTargets` relies on derived `Ord`, and
|
||
|
|
- `totalFailureBudget` relies on derived `Num`.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 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:
|
||
|
|
|
||
|
|
- `Priority` lists `Urgent` before `Standard` and `Background`, so urgent work sorts first, and
|
||
|
|
- `ReleaseTarget` stores 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:
|
||
|
|
|
||
|
|
- `BatchName` derives `Semigroup` and `Monoid`, and
|
||
|
|
- `FailureBudget` derives `Num` and `Ord`.
|
||
|
|
|
||
|
|
That means the code can concatenate names and sum budgets without unpacking the wrappers everywhere.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Commands to Try
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd 24-haskell-deriving
|
||
|
|
|
||
|
|
nix develop
|
||
|
|
cabal run
|
||
|
|
cabal test
|
||
|
|
|
||
|
|
nix build
|
||
|
|
./result/bin/mini-deriving
|
||
|
|
|
||
|
|
nix run
|
||
|
|
nix flake check
|
||
|
|
```
|