Haskell Conventions
Type Design
- •Newtype wrappers for domain primitives (
UserId,Email) -- never rawInt/Text - •Smart constructors to enforce invariants at construction time
- •Sum types for states -- never booleans for mutually exclusive states
Error Handling
- •
Either/ExceptTfor expected, recoverable errors - •
throwIOfor unexpected, unrecoverable errors - •Never use partial functions:
head,tail,fromJust,read
Application Structure
- •ReaderT pattern (
ReaderT AppEnv IO) over deep transformer stacks - •MTL-style typeclasses for effect abstraction when needed
- •Avoid stacking more than 2-3 transformers
Strictness
- •Use
Text, neverString(unless legacy interop) - •Strict IO (
Data.Text.IO) over lazy IO - •Use streaming (conduit/pipes) for large data
Concurrency
- •
STM/TVarfor shared mutable state - •
async/mapConcurrentlyfor concurrent tasks - •
racefor timeouts
Anti-patterns
- •
Stringfor text data - •Lazy IO (
Prelude.readFile) - •Deep monad transformer stacks
- •Boolean parameters instead of sum types
- •Partial functions