-- | -- Module: Optics.IxAffineTraversal -- Description: An indexed version of an 'Optics.AffineTraversal.AffineTraversal'. -- -- An 'IxAffineTraversal' is an indexed version of an -- 'Optics.AffineTraversal.AffineTraversal'. See the "Indexed optics" section -- of the overview documentation in the @Optics@ module of the main @optics@ -- package for more details on indexed optics. -- module Optics.IxAffineTraversal ( -- * Formation IxAffineTraversal , IxAffineTraversal' -- * Introduction , iatraversal -- * Elimination -- | An 'IxAffineTraversal' is in particular an -- 'Optics.IxAffineFold.IxAffineFold' and an 'Optics.IxSetter.IxSetter', -- therefore you can specialise types to obtain: -- -- @ -- 'Optics.IxAffineFold.ipreview' :: 'IxAffineTraversal' i s t a b -> s -> Maybe (i, a) -- @ -- -- @ -- 'Optics.IxSetter.iover' :: 'IxAffineTraversal' i s t a b -> (i -> a -> b) -> s -> t -- 'Optics.IxSetter.iset' :: 'IxAffineTraversal' i s t a b -> (i -> b) -> s -> t -- @ -- * Combinators , unsafeFilteredBy -- * Additional introduction forms , ignored -- * Subtyping , An_AffineTraversal -- * van Laarhoven encoding , IxAffineTraversalVL , IxAffineTraversalVL' , iatraversalVL , iatraverseOf ) where import Data.Profunctor.Indexed import Optics.AffineFold import Optics.Internal.Indexed import Optics.Internal.Optic import Optics.Internal.Utils -- | Type synonym for a type-modifying indexed affine traversal. type IxAffineTraversal i s t a b = Optic An_AffineTraversal (WithIx i) s t a b -- | Type synonym for a type-preserving indexed affine traversal. type IxAffineTraversal' i s a = Optic' An_AffineTraversal (WithIx i) s a -- | Type synonym for a type-modifying van Laarhoven indexed affine traversal. -- -- Note: this isn't exactly van Laarhoven representation as there is no -- @Pointed@ class (which would be a superclass of 'Applicative' that contains -- 'pure' but not '<*>'). You can interpret the first argument as a dictionary -- of @Pointed@ that supplies the @point@ function (i.e. the implementation of -- 'pure'). -- type IxAffineTraversalVL i s t a b = forall f. Functor f => (forall r. r -> f r) -> (i -> a -> f b) -> s -> f t -- | Type synonym for a type-preserving van Laarhoven indexed affine traversal. type IxAffineTraversalVL' i s a = IxAffineTraversalVL i s s a a -- | Build an indexed affine traversal from a matcher and an updater. -- -- If you want to build an 'IxAffineTraversal' from the van Laarhoven -- representation, use 'iatraversalVL'. iatraversal :: (s -> Either t (i, a)) -> (s -> b -> t) -> IxAffineTraversal i s t a b iatraversal match update = iatraversalVL $ \point f s -> either point (\a -> update s <$> uncurry' f a) (match s) {-# INLINE iatraversal #-} -- | Build an indexed affine traversal from the van Laarhoven representation. iatraversalVL :: IxAffineTraversalVL i s t a b -> IxAffineTraversal i s t a b iatraversalVL f = Optic (ivisit f) {-# INLINE iatraversalVL #-} -- | Traverse over the target of an 'IxAffineTraversal' and compute a -- 'Functor'-based answer. -- -- @since 0.3 iatraverseOf :: (Is k An_AffineTraversal, Functor f, is `HasSingleIndex` i) => Optic k is s t a b -> (forall r. r -> f r) -> (i -> a -> f b) -> s -> f t iatraverseOf o point = \f -> runIxStarA (getOptic (castOptic @An_AffineTraversal o) (IxStarA point f)) id {-# INLINE iatraverseOf #-} -- | Obtain a potentially empty 'IxAffineTraversal' by taking the element from -- another 'AffineFold' and using it as an index. -- -- -- /Note:/ This is /not/ a legal 'Optics.IxTraversal.IxTraversal', unless you -- are very careful not to invalidate the predicate on the target (see -- 'Optics.AffineTraversal.unsafeFiltered' for more details). -- -- @since 0.3 unsafeFilteredBy :: Is k An_AffineFold => Optic' k is a i -> IxAffineTraversal' i a a unsafeFilteredBy p = iatraversalVL $ \point f s -> case preview p s of Just i -> f i s Nothing -> point s {-# INLINE unsafeFilteredBy #-} -- | This is the trivial empty 'IxAffineTraversal', i.e. the optic that targets -- no substructures. -- -- This is the identity element when a 'Optics.Fold.Fold', -- 'Optics.AffineFold.AffineFold', 'Optics.IxFold.IxFold', -- 'Optics.IxAffineFold.IxAffineFold', 'Optics.Traversal.Traversal' or -- 'Optics.IxTraversal.IxTraversal' is viewed as a monoid. -- -- >>> 6 & ignored %~ absurd -- 6 ignored :: IxAffineTraversal i s s a b ignored = iatraversalVL $ \point _ -> point {-# INLINE ignored #-} -- $setup -- >>> import Optics.Core -- >>> import Data.Void (absurd)