Build field optics as instances of the LabelOptic class for use with overloaded labels. See Optics.Label for how to use this pattern.
e.g.
data Animal
= Cat { animalAge :: Int
, animalName :: String
}
| Dog { animalAge :: Int
, animalAbsurd :: forall a b. a -> b
}
makeFieldLabels ''Animal
will create
instance
(k ~ A_Lens, a ~ Int, b ~ Int
) => LabelOptic "age" k Animal Animal a b where
labelOptic = lensVL $ \f s -> case s of
Cat x1 x2 -> fmap (\y -> Cat y x2) (f x1)
Dog x1 x2 -> fmap (\y -> Dog y x2) (f x1)
instance
(k ~ An_AffineTraversal, a ~ String, b ~ String
) => LabelOptic "name" k Animal Animal a b where
labelOptic = atraversalVL $ \point f s -> case s of
Cat x1 x2 -> fmap (\y -> Cat x1 y) (f x2)
Dog x1 x2 -> point (Dog x1 x2)
instance
( Dysfunctional "absurd" k Animal Animal a b
, k ~ An_AffineFold, a ~ (x -> y), b ~ (x -> y)
) => LabelOptic "absurd" k Animal Animal a b where
labelOptic = afolding $ \s -> case s of
Cat _ _ -> Nothing
Dog _ f -> Just f
which can be used as #age, #name and #absurd with the
OverloadedLabels language extension.
Note: if you wonder about the structure of instances, see
Optics.Label#structure.
makeFieldOptics = makeFieldLabelsWith fieldLabelsRules