74 lines
2.0 KiB
Markdown
74 lines
2.0 KiB
Markdown
|
|
# Haskell Maybe and Either
|
||
|
|
|
||
|
|
This note covers `23-haskell-maybe-either/`, which builds a release request from `key=value` inputs by using `Maybe` for optional data and `Either`
|
||
|
|
for validation failures.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. Why Both Types Matter
|
||
|
|
|
||
|
|
`Maybe` answers one question: is a value present or absent?
|
||
|
|
|
||
|
|
`Either` answers a different question: if something failed, why?
|
||
|
|
|
||
|
|
This example uses both on purpose:
|
||
|
|
|
||
|
|
- optional fields such as `owner` stay as `Maybe`,
|
||
|
|
- required fields start as lookups that may be absent, and
|
||
|
|
- missing or invalid required data becomes `Either String ...` with an error message.
|
||
|
|
|
||
|
|
That gives the program a clean progression from raw input toward a validated domain value.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. Where `Maybe` Shows Up
|
||
|
|
|
||
|
|
The input is a flat list of assignments such as `service=api` and `owner=platform`.
|
||
|
|
|
||
|
|
`lookupOptional` searches that list and returns `Maybe String`:
|
||
|
|
|
||
|
|
```haskell
|
||
|
|
lookupOptional :: String -> [(String, String)] -> Maybe String
|
||
|
|
```
|
||
|
|
|
||
|
|
That is the right level for values that are genuinely optional. In the example, `owner` can be absent without making the whole request invalid.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Where `Either` Takes Over
|
||
|
|
|
||
|
|
Required fields cannot stay as `Maybe`, because the rest of the program needs a reason when construction fails.
|
||
|
|
|
||
|
|
The example upgrades a missing field into an error:
|
||
|
|
|
||
|
|
```haskell
|
||
|
|
lookupRequired :: String -> [(String, String)] -> Either String String
|
||
|
|
```
|
||
|
|
|
||
|
|
It then adds more validation:
|
||
|
|
|
||
|
|
- environment parsing,
|
||
|
|
- replica count parsing, and
|
||
|
|
- canary percentage rules for the rollout strategy.
|
||
|
|
|
||
|
|
That keeps absence and validation separate, which makes the control flow easier to read.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Commands to Try
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd 23-haskell-maybe-either
|
||
|
|
|
||
|
|
nix develop
|
||
|
|
cabal run
|
||
|
|
cabal run -- service=api env=production replicas=3 strategy=canary canary=10 owner=platform
|
||
|
|
cabal test
|
||
|
|
|
||
|
|
nix build
|
||
|
|
./result/bin/mini-release-request service=api env=production replicas=3 strategy=canary canary=10 owner=platform
|
||
|
|
|
||
|
|
nix run . -- service=api env=production replicas=3 strategy=canary canary=10 owner=platform
|
||
|
|
nix flake check
|
||
|
|
```
|