Template Haskell to generate lenses for lens-family and lens-family-core
Haskell
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Lens version bump; remove unneeded type applications May 27, 2016
examples
.gitignore
LICENSE
README.md
Setup.hs
lens-family-th.cabal
stack.yaml

README.md

lens-family-th

Template Haskell to generate lenses for lens-family and lens-family-core.

Usage:

{-# LANGUAGE TemplateHaskell, Rank2Types #-}

import Lens.Family2
import Lens.Family2.TH

data Foo a = Foo { _bar :: Int, _baz :: a }
         deriving (Show, Read, Eq, Ord)
$(makeLenses ''Foo)

This will create lenses bar and baz.

You can instead create these lenses by hand as explained by documentation at Lens.Family.Unchecked.

makeLenses merely generates the following definition for each field, making use of Haskell's record update syntax:

lensName f a = (\x -> a { fieldName = x }) `fmap` f (fieldName a)

makeLenses will refuse to create lenses for data declarations with more than 1 constructor.


For data types with multiple constructors, you can use makeTraversals. For example:

{-# LANGUAGE TemplateHaskell, Rank2Types #-}

import Lens.Family2
import Lens.Family2.TH

data T a c d = A a | B | CD c d Int
$(makeTraversals ''T)

Will create traversals _A, _B, and _C in this fashion:

_A k (A a) = fmap (\a -> A a) (k a)
_A _  B    = pure B
_A _ (C c d i) = pure (C c d i)

_B _ (A a) = pure (A a)
_B k B = fmap (\() -> B) (k ())
_B _ (C c d i) = pure (C c d i)

_C _ (A a) = pure (A a)
_C _ B = pure B
_C k (C c d i) = fmap (\(c',d',i') -> C c' d' i') (k (c,d,i))