miso
Copyright(C) 2016-2026 David M. Johnson
LicenseBSD3-style (see the file LICENSE)
MaintainerDavid M. Johnson <code@dmj.io>
Stabilityexperimental
Portabilitynon-portable
Safe HaskellSafe-Inferred
LanguageHaskell2010

Miso.Lens.TH

Contents

Description

Overview

Miso.Lens.TH generates Lens definitions via Template Haskell, similar to lens's makeLenses and makeClassy. Fields must be prefixed with _ — the generated lens name is the field name with the underscore dropped.

Enable the extension and splice at the declaration level:

{-# LANGUAGE TemplateHaskell #-}
import Miso.Lens.TH (makeLenses, makeClassy)

makeLenses

Generates a Lens Record Field for each _-prefixed record field:

data Model = Model
  { _count :: Int
  , _text  :: MisoString
  } deriving (Eq)

makeLenses ''Model
-- Generates:
--   count :: Lens Model Int
--   text  :: Lens Model MisoString

update :: Action -> Effect p props Model Action
update Increment   = count += 1
update (SetText t) = text  .= t

makeClassy

Generates a HasFoo typeclass with a self-lens foo :: Lens s Foo and one lens per _-prefixed field. This enables lens composition across record types that embed Foo:

data Foo = Foo { _fooX :: Int, _fooY :: Int }
makeClassy ''Foo
-- Generates:
--   class HasFoo s where
--     foo  :: Lens s Foo
--     fooX :: Lens s Int   -- fooX = foo . lens _fooX ...
--     fooY :: Lens s Int
--   instance HasFoo Foo where foo = this

data Bar = Bar { _barFoo :: Foo, _barZ :: Double }
makeLenses ''Bar
instance HasFoo Bar where foo = barFoo
-- Now barX :: Lens Bar Int  (via foo composition)

Comparison with Generic approach

Template Haskell
Miso.Lens.TH_ prefix required; explicit splice
Overloaded labels
Miso.Lens.Generic — no TH; derives via Generic

See also

Synopsis

TH

makeLenses Source #

Arguments

:: Name

The name of the record type to derive lenses for (e.g. ''MyModel)

-> Q [Dec] 

Automatically generates Haskell lenses via template-haskell.

makeClassy Source #

Arguments

:: Name

The name of the record type to derive a Has typeclass and lenses for (e.g. ''MyModel)

-> Q [Dec] 

Automatically generates classy lenses via template-haskell.

Re-exports

lens Source #

Arguments

:: (record -> field)

Getter: read the field from a record

-> (record -> field -> record)

Setter: write a new field value into a record

-> Lens record field 

Smart constructor lens function. Used to easily construct a Lens

name :: 'Lens' Person String
name = 'lens' _name $ \p n -> p { _name = n }

compose :: Category cat => cat a b -> cat b c -> cat a c Source #

Function composition generalized to Category

test :: Int -> Int
test = (+1) `compose` (+1)

this :: Lens a a Source #

Lens that operates on itself

update AddOne = do
  this += 1

type Lens s a = LensCore a s Source #

A Lens is a generalized getter and setter.

Lenses allow both the retrieval of values from fields in a record and the assignment of values to fields in a record. The power of a Lens comes from its ability to be composed with other lenses.

In the context of building applications with miso, the model is often a deeply nested product type. This makes it highly conducive to Lens operations (as defined below).