| name | haskell-effectful |
| description | Effectful library conventions and decision rules. Use when writing effectful code, designing effects, or migrating from mtl. |
Effectful Conventions
Dispatch Choice
- Default: Static (
Effectful.Reader.Static, Effectful.State.Static.Local)
- Only use Dynamic when MonadReader/MonadState instances are needed
Effect Stack Order
Always consistent: Reader -> State -> Error -> IOE
runApp :: Config -> AppState -> App a -> IO (Either (CallStack, AppError) (a, AppState))
runApp cfg st = runEff . runError . runStateLocal st . runReader cfg
Custom Effects
Definition
- Default: Use
makeEffect from Effectful.TH to auto-generate smart constructors and DispatchOf instances
- Manual definition required when GADTs have effect constraints (e.g.,
Error e :> es) or custom naming
Handlers
- First-order (no
m parameter): use interpret_
- Higher-order (uses
m parameter): use interpret + localSeqUnlift
Error Handling
- Put
Error constraints on GADT constructors, not on handler signatures -- caller decides error scope
- Error.Static lacks MonadError -- define local
liftEither helper
- Use
runErrorNoCallStack or runErrorWith at boundaries
- Derive
Exception on error newtypes for IO interop