records-edsl: Write less record boilerplate

[ library, mpl, records ] [ Propose Tags ] [ Report a vulnerability ]

Cut off your boilerplate, eschew boilers entirely, and replace them with a small teapot perched atop a small but slightly foreboding volcano.

This package defines a small EDSL to define records.

Provides an eDSL for defining record data-types and a closed vessel in which fluid (generally water) is heated worth of boilerplate.

Defining a record type in this eDSL rather than plain Haskell gets you:

  • Records without clashing names

  • Syntax to access fields on records without Hungarian-notation prefixes on every field (via GHC.HasField and Optics.LabelOptic)

  • Declarative syntax for defining that a field has an external representation you want to use for its, for example, ToJSON , FromJSON , or ToSchema

This is accomplished with the help of the excellent "witch" library.

  • ToSchema instances with per-field field descriptions as per your comment on each field

  • ToSchema instances with per-type descriptions

The EDSL also lets you extend what instances you get. The Deriver type defines how instances are defined.

Example:

We *can* write:

declareSchemaRecords deriveAll """
record Test --field-prefix=test {
  foo :: Int,
  bar :: MyType via MyTypeJSONRepr,
}
"""

But maybe you prefer:

data Test = Test
  { testFoo :: Int
  , testBar :: MyType
  }
  deriving stock (Show, Generic, Eq)
  deriving (Arbitrary) via (GenericArbitraryU Test)

instance O.ToSchema Test where
  declareNamedSchema _ = ...
  -- ... instance using 'foo' as 'Int' and 'bar' as 'MyTypeJSONRepr'
  -- converting 'bar' using @ 'from' @
  --
  -- I'm so allergic to writing this by hand that I can't even be
  -- bothered to put it into an example. Rest assured, it's annoying
  -- and easy to make mistakes with.

instance O.ToJSON Test where
  toJSON _ = ...
  toEncoding _ = ...
  -- ... instance using 'foo' as 'Int' and 'bar' as 'MyTypeJSONRepr'
  -- converting 'bar' using @ 'from' @.

instance O.FromJSON Test where
  parseJSON = ...
  -- ... instance parsing 'foo' as 'Int' and 'bar' as 'MyTypeJSONRepr'
  -- converting 'bar' using @ 'from' @

In actual examples the hand-written code is 8-10 times larger than with the declarative syntax.

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1.0
Dependencies base (<5), records-edsl-core (>=0.1.0 && <0.2), records-edsl-deriving-aeson (>=0.1.0 && <0.2), records-edsl-deriving-openapi3 (>=0.1.0 && <0.2), records-edsl-deriving-optics (>=0.1.0 && <0.2), records-edsl-deriving-quickcheck (>=0.1.0 && <0.2) [details]
License MPL-2.0
Author Mike Ledger
Maintainer Mike Ledger <mike@quasimal.com>
Uploaded by MikeLedger at 2026-05-11T15:03:34Z
Category Records
Source repo head: git clone https://gitlab.com/combobulate.systems/records-edsl.git
Distributions
Downloads 2 total (2 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user [build log]
All reported builds failed as of 2026-05-11 [all 2 reports]