| Copyright | (C) 2016-2026 David M. Johnson |
|---|---|
| License | BSD3-style (see the file LICENSE) |
| Maintainer | David M. Johnson <code@dmj.io> |
| Stability | experimental |
| Portability | non-portable |
| Safe Haskell | None |
| Language | Haskell2010 |
Miso.Lens.Generic
Contents
Description
Overview
Miso.Lens.Generic derives Lens values for record fields
at compile time using GHC.Generics and GHC.Records, without
Template Haskell. Fields are addressed by name via OverloadedLabels
or the explicit field combinator.
Enable the required extensions:
{-# LANGUAGE OverloadedLabels, DeriveGeneric #-}
import GHC.Generics (Generic)
import Miso.Lens.Generic (HasLens, field)
import Miso.Lens (Lens, view, set, (.=), (++=))
Quick start
data Counter = Counter { _count :: Int, _label :: MisoString }
deriving (Generic)
-- Label syntax (requires OverloadedLabels):
countLens :: Lens Counter Int
countLens = #_count
-- Explicit syntax (works without OverloadedLabels):
labelLens :: Lens Counter MisoString
labelLens = field @"_label"
update :: Action -> Effect p props Counter Action
update Increment = #_count += 1
update (SetLabel l) = #_label .= l
How it works
The HasLens instance is resolved via HasField for the
getter and a generic traversal (GSet) for the setter. A type-level
TotalityCheck produces a descriptive compile error if the field name
is absent from (or inconsistent across) the constructors.
Comparison with Template Haskell
- Overloaded labels
- Miso.Lens.Generic — no TH; derives via
Generic - Template Haskell
- Miso.Lens.TH —
makeLenses/makeClassy
See also
- Miso.Lens —
Lens,lens, operators - Miso.Lens.TH — Template Haskell alternative