← ClaudeAtlas

haskell-domain-errorslisted

Model errors as Haskell domain types with structured context, hand-written Show for humans, explicit-tag ToJSON for logs, and conscious choices about Exception/FromJSON. Use when designing error ADTs, deciding between Either/Error effect/throwIO, writing instances for errors, or reviewing error-handling code.
ivelten/claude-haskell-skills · ★ 0 · AI & Automation · score 60
Install: claude install-skill ivelten/claude-haskell-skills
# Haskell Domain Errors Errors are domain types, not strings. Each error constructor carries the structured context relevant to the failure. Rendering for humans and serialization for logs are *separate concerns* on top of that structured type. The error type *is* the data; how it surfaces (return value, effect, exception) is an orthogonal decision. ## The pattern ```haskell {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} import Data.Aeson (ToJSON(..), object, (.=)) import Data.Text (Text) import qualified Data.Text as T import GHC.Generics (Generic) data RegistrationError = EmailAlreadyExists Email | InvalidEmailFormat Text -- ^ the raw input that failed | PasswordTooShort Int Int -- ^ received length, minimum required | DatabaseUnavailable Text -- ^ driver message deriving stock (Eq, Generic) -- Human-readable Show: ready for console, log line, or UI message. instance Show RegistrationError where show = \case EmailAlreadyExists (Email e) -> "Email already registered: " <> T.unpack e InvalidEmailFormat raw -> "Invalid email format: " <> show raw PasswordTooShort got need -> "Password too short: got " <> show got <> " chars, need at least " <> show need DatabaseUnavailable reason -> "Database unavailable: " <> T.unpack reason -- Structured JSON: tagged discriminator + payload, suitable for log aggregators