Build lenses (and traversals) with a sensible default configuration.
e.g.
data FooBar
= Foo { _x, _y :: Int }
| Bar { _x :: Int }
makeLenses ''FooBar
will create
x :: Lens' FooBar Int
x f (Foo a b) = (\a' -> Foo a' b) <$> f a
x f (Bar a) = Bar <$> f a
y :: Traversal' FooBar Int
y f (Foo a b) = (\b' -> Foo a b') <$> f b
y _ c@(Bar _) = pure c
Make lenses and traversals for a type, and create a class when the
type has no arguments.
e.g.
data Foo = Foo { _fooX, _fooY :: Int }
makeClassy ''Foo
will create
class HasFoo t where
foo :: Lens' t Foo
fooX :: Lens' t Int
fooX = foo . go where go f (Foo x y) = (\x' -> Foo x' y) <$> f x
fooY :: Lens' t Int
fooY = foo . go where go f (Foo x y) = (\y' -> Foo x y') <$> f y
instance HasFoo Foo where
foo = id
Make lenses and traversals for a type, and create a class when the type
has no arguments. Works the same as makeClassy except that (a) it
expects that record field names do not begin with an underscore, (b) all
record fields are made into lenses, and (c) the resulting lens is prefixed
with an underscore.
data Foo a = Foo { _fooX :: Int, _fooY :: a }
newtype Bar = Bar { _barX :: Char }
makeFields ''Foo
makeFields ''Bar
will create
_fooXLens :: Lens' (Foo a) Int
_fooYLens :: Lens (Foo a) (Foo b) a b
class HasX s a | s -> a where
x :: Lens' s a
instance HasX (Foo a) Int where
x = _fooXLens
class HasY s a | s -> a where
y :: Lens' s a
instance HasY (Foo a) a where
y = _fooYLens
_barXLens :: Iso' Bar Char
instance HasX Bar Char where
x = _barXLens
Generate overloaded field accessors based on field names which
are only prefixed with an underscore (e.g. _name), not
additionally with the type name (e.g. _fooName).
This might be the desired behaviour in case the
DuplicateRecordFields language extension is used in order to get
rid of the necessity to prefix each field name with the type name.
As an example:
data Foo a = Foo { _x :: Int, _y :: a }
newtype Bar = Bar { _x :: Char }
makeFieldsNoPrefix ''Foo
makeFieldsNoPrefix ''Bar
will create classes
class HasX s a | s -> a where
x :: Lens' s a
class HasY s a | s -> a where
y :: Lens' s a
together with instances
instance HasX (Foo a) Int
instance HasY (Foo a) a where
instance HasX Bar Char where
Generate overloaded field accessors, using exactly the same names as the
underlying fields. Intended for use with the NoFieldSelectors and
DuplicateRecordFields language extensions.
As an example:
data Foo a = Foo { x :: Int, y :: a }
newtype Bar = Bar { x :: Char }
makeFieldsId ''Foo
makeFieldsId ''Bar
will create classes
class HasX s a | s -> a where
x :: Lens' s a
class HasY s a | s -> a where
y :: Lens' s a
together with instances
instance HasX (Foo a) Int
instance HasY (Foo a) a where
instance HasX Bar Char where
Generate a Prism for each constructor of a data type.
Isos generated when possible.
Reviews are created for constructors with existentially
quantified constructors and GADTs.
e.g.
data FooBarBaz a
= Foo Int
| Bar a
| Baz Int Char
makePrisms ''FooBarBaz
will create
_Foo :: Prism' (FooBarBaz a) Int
_Bar :: Prism (FooBarBaz a) (FooBarBaz b) a b
_Baz :: Prism' (FooBarBaz a) (Int, Char)
Generate a Prism for each constructor of a data type
and combine them into a single class. No Isos are created.
Reviews are created for constructors with existentially
quantified constructors and GADTs.
e.g.
data FooBarBaz a
= Foo Int
| Bar a
| Baz Int Char
makeClassyPrisms ''FooBarBaz
will create
class AsFooBarBaz s a | s -> a where
_FooBarBaz :: Prism' s (FooBarBaz a)
_Foo :: Prism' s Int
_Bar :: Prism' s a
_Baz :: Prism' s (Int,Char)
_Foo = _FooBarBaz . _Foo
_Bar = _FooBarBaz . _Bar
_Baz = _FooBarBaz . _Baz
instance AsFooBarBaz (FooBarBaz a) a
Generate an As class of prisms. Names are selected by prefixing the constructor
name with an underscore. Constructors with multiple fields will
construct Prisms to tuples of those fields.
In the event that the name of a data type is also the name of one of its
constructors, the name of the Prism generated for the data type will be
prefixed with an extra _ (if the data type name is prefix) or . (if the
name is infix) to disambiguate it from the Prism for the corresponding
constructor. For example, this code:
data Quux = Quux Int | Fred Bool
makeClassyPrisms ''Quux
will create:
class AsQuux s where
__Quux :: Prism' s Quux -- Data type prism
_Quux :: Prism' s Int -- Constructor prism
_Fred :: Prism' s Bool
_Quux = __Quux . _Quux
_Fred = __Quux . _Fred
instance AsQuux Quux
For each record in the declaration quote, make lenses and traversals for
it, and create a class when the type has no arguments. All record syntax
in the input will be stripped off.
e.g.
declareClassy [d|
data Foo = Foo { fooX, fooY :: Int }
deriving Show
|]
will create
data Foo = Foo IntInt deriving Show
class HasFoo t where
foo :: Lens' t Foo
instance HasFoo Foo where foo = id
fooX, fooY :: HasFoo t => Lens' t Int
Rules for making fairly simple partial lenses, ignoring the special cases
for isomorphisms and traversals, and not making any classes.
It uses underscoreNoPrefixNamer.
Field rules for fields in the form prefixFieldname or _prefixFieldname
If you want all fields to be lensed, then there is no reason to use an _ before the prefix.
If any of the record fields leads with an _ then it is assume a field without an _ should not have a lens created.
Note: The prefix must be the same as the typename (with the first
letter lowercased). This is a change from lens versions before lens 4.5.
If you want the old behaviour, use makeLensesWithabbreviatedFields
Field rules for fields in the form _fieldname (the leading
underscore is mandatory).
Note: The primary difference to camelCaseFields is that for
classUnderscoreNoPrefixFields the field names are not expected to
be prefixed with the type name. This might be the desired behaviour
when the DuplicateRecordFields extension is enabled.
Field rules fields in the form prefixFieldname or _prefixFieldname
If you want all fields to be lensed, then there is no reason to use an _ before the prefix.
If any of the record fields leads with an _ then it is assume a field without an _ should not have a lens created.
Note that prefix may be any string of characters that are not uppercase
letters. (In particular, it may be arbitrary string of lowercase letters
and numbers) This is the behavior that defaultFieldRules had in lens
4.4 and earlier.
Generate "updateable" optics when True. When False, Folds will be
generated instead of Traversals and Getters will be generated instead
of Lenses. This mode is intended to be used for types with invariants
which must be maintained by "smart" constructors.
> undefined & x .~ 8 & y .~ True
Foo {_x = 8, _y = True}
The downside of this flag is that it can lead to space-leaks and
code-size/compile-time increases when generated for large records. By
default this flag is turned off, and strict optics are generated.
When using lazy optics the strict optic can be recovered by composing
with $!: