    -- |
    -- Module: Optics.Fold
    -- Description: Extracts elements from a container.
    --
    -- A @'Fold' S A@ has the ability to extract some number of elements of type @A@
    -- from a container of type @S@.  For example, 'toListOf' can be used to obtain
    -- the contained elements as a list. Unlike a 'Optics.Traversal.Traversal',
    -- there is no way to set or update elements.
    --
    -- This can be seen as a generalisation of 'traverse_', where the type @S@ does
    -- not need to be a type constructor with @A@ as the last parameter.
    --
    -- A close relative is the 'Optics.AffineFold.AffineFold', which is a 'Fold'
    -- that contains at most one element.
    --
    module Optics.Fold
      (
      -- * Formation
        Fold

      -- * Introduction
      , foldVL

      -- * Elimination
      , foldOf
      , foldMapOf
      , foldrOf
      , foldlOf'
      , toListOf
      , sequenceOf_
      , traverseOf_
      , forOf_

      -- * Computation
      --
      -- |
      --
      -- @
      -- 'traverseOf_' ('foldVL' f) ≡ f
      -- @

      -- * Additional introduction forms
      , folded
      , folding
      , foldring
      , unfolded

      -- * Additional elimination forms
      -- | See also 'Data.Set.Optics.setOf', which constructs a 'Data.Set.Set' from a 'Fold'.
      , has
      , hasn't
      , headOf
      , lastOf
      , andOf
      , orOf
      , allOf
      , anyOf
      , noneOf
      , productOf
      , sumOf
      , asumOf
      , msumOf
      , elemOf
      , notElemOf
      , lengthOf
      , maximumOf
      , minimumOf
      , maximumByOf
      , minimumByOf
      , findOf
      , findMOf
      , lookupOf
      , universeOf
      , cosmosOf
      , paraOf

      -- * Combinators
      , pre
      , backwards_

      -- * Monoid structures #monoids#
      -- | 'Fold' admits (at least) two monoid structures:
      --
      -- * 'summing' concatenates results from both folds.
      --
      -- * 'failing' returns results from the second fold only if the first returns
      --   no results.
      --
      -- In both cases, the identity element of the monoid is
      -- `Optics.IxAffineTraversal.ignored`, which returns no results.
      --
      -- There is no 'Semigroup' or 'Monoid' instance for 'Fold', because there is
      -- not a unique choice of monoid to use, and the ('<>') operator could not be
      -- used to combine optics of different kinds.  When porting code from @lens@
      -- that uses '<>' to combine folds, use 'summing' instead.
      , summing
      , failing

      -- * Subtyping
      , A_Fold
      -- | <<diagrams/Fold.png Fold in the optics hierarchy>>
      )
      where

    import Control.Applicative
    import Control.Applicative.Backwards
    import Control.Monad
    import Data.Foldable
    import Data.Function
    import Data.Monoid

    import Data.Profunctor.Indexed

    import Optics.AffineFold
    import Optics.Internal.Bi
    import Optics.Internal.Fold
    import Optics.Internal.Optic
    import Optics.Internal.Utils

    -- | Type synonym for a fold.
    type Fold s a = Optic' A_Fold NoIx s a

    -- | Obtain a 'Fold' by lifting 'traverse_' like function.
    --
    -- @
    -- 'foldVL' '.' 'traverseOf_' ≡ 'id'
    -- 'traverseOf_' '.' 'foldVL' ≡ 'id'
    -- @
    foldVL
      :: (forall f. Applicative f => (a -> f u) -> s -> f v)
      -> Fold s a
    foldVL :: forall a u s v.
    (forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v)
    -> Fold s a
    foldVL forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v
    f = (forall (p :: * -> * -> * -> *) i.
     Profunctor p =>
     Optic_ A_Fold p i (Curry NoIx i) s s a a)
    -> Optic A_Fold NoIx s s a a
    forall k (is :: IxList) s t a b.
    (forall (p :: * -> * -> * -> *) i.
     Profunctor p =>
     Optic_ k p i (Curry is i) s t a b)
    -> Optic k is s t a b
    Optic ((forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v)
    -> Optic__ p i i s s a a
    forall (p :: * -> * -> * -> *) a u s v i t b.
    (Bicontravariant p, Traversing p) =>
    (forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v)
    -> Optic__ p i i s t a b
    foldVL__ (a -> f u) -> s -> f v
    forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v
    f)
    {-# INLINE foldVL #-}

    -- | Combine the results of a fold using a monoid.
    foldOf :: (Is k A_Fold, Monoid a) => Optic' k is s a -> s -> a
    foldOf :: forall k a (is :: IxList) s.
    (Is k A_Fold, Monoid a) =>
    Optic' k is s a -> s -> a
    foldOf Optic' k is s a
    o = Optic' k is s a -> (a -> a) -> s -> a
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o a -> a
    forall a. a -> a
    id
    {-# INLINE foldOf #-}

    -- | Fold via embedding into a monoid.
    foldMapOf :: (Is k A_Fold, Monoid m) => Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf :: forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o = Forget m (Curry is (ZonkAny 1)) s s -> s -> m
    forall r i a b. Forget r i a b -> a -> r
    runForget (Forget m (Curry is (ZonkAny 1)) s s -> s -> m)
    -> (Forget m (ZonkAny 1) a a
        -> Forget m (Curry is (ZonkAny 1)) s s)
    -> Forget m (ZonkAny 1) a a
    -> s
    -> m
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. Optic A_Fold is s s a a
    -> Optic_
         A_Fold (Forget m) (ZonkAny 1) (Curry is (ZonkAny 1)) s s a a
    forall (p :: * -> * -> * -> *) k (is :: IxList) s t a b i.
    Profunctor p =>
    Optic k is s t a b -> Optic_ k p i (Curry is i) s t a b
    getOptic (forall destKind srcKind (is :: IxList) s t a b.
    Is srcKind destKind =>
    Optic srcKind is s t a b -> Optic destKind is s t a b
    castOptic @A_Fold Optic' k is s a
    o) (Forget m (ZonkAny 1) a a -> s -> m)
    -> ((a -> m) -> Forget m (ZonkAny 1) a a) -> (a -> m) -> s -> m
    forall a b c. Coercible a b => (b -> c) -> (a -> b) -> a -> c
    .# (a -> m) -> Forget m (ZonkAny 1) a a
    forall r i a b. (a -> r) -> Forget r i a b
    Forget
    {-# INLINE foldMapOf #-}

    -- | Fold right-associatively.
    foldrOf :: Is k A_Fold => Optic' k is s a -> (a -> r -> r) -> r -> s -> r
    foldrOf :: forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (a -> r -> r) -> r -> s -> r
    foldrOf Optic' k is s a
    o = \a -> r -> r
    arr r
    r s
    s -> (\Endo r
    e -> Endo r -> r -> r
    forall a. Endo a -> a -> a
    appEndo Endo r
    e r
    r) (Endo r -> r) -> Endo r -> r
    forall a b. (a -> b) -> a -> b
    $ Optic' k is s a -> (a -> Endo r) -> s -> Endo r
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o ((r -> r) -> Endo r
    forall a. (a -> a) -> Endo a
    Endo ((r -> r) -> Endo r) -> (a -> r -> r) -> a -> Endo r
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. a -> r -> r
    arr) s
    s
    {-# INLINE foldrOf #-}

    -- | Fold left-associatively, and strictly.
    foldlOf' :: Is k A_Fold => Optic' k is s a -> (r -> a -> r) -> r -> s -> r
    foldlOf' :: forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (r -> a -> r) -> r -> s -> r
    foldlOf' Optic' k is s a
    o = \r -> a -> r
    rar r
    r0 s
    s -> Optic' k is s a
    -> (a -> (r -> r) -> r -> r) -> (r -> r) -> s -> r -> r
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (a -> r -> r) -> r -> s -> r
    foldrOf Optic' k is s a
    o (\a
    a r -> r
    rr r
    r -> r -> r
    rr (r -> r) -> r -> r
    forall a b. (a -> b) -> a -> b
    $! r -> a -> r
    rar r
    r a
    a) r -> r
    forall a. a -> a
    id s
    s r
    r0
    {-# INLINE foldlOf' #-}

    -- | Fold to a list.
    --
    -- >>> toListOf (_1 % folded % _Right) ([Right 'h', Left 5, Right 'i'], "bye")
    -- "hi"
    toListOf :: Is k A_Fold => Optic' k is s a -> s -> [a]
    toListOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> s -> [a]
    toListOf Optic' k is s a
    o = Optic' k is s a -> (a -> [a] -> [a]) -> [a] -> s -> [a]
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (a -> r -> r) -> r -> s -> r
    foldrOf Optic' k is s a
    o (:) []
    {-# INLINE toListOf #-}

    ----------------------------------------

    -- | Traverse over all of the targets of a 'Fold', computing an
    -- 'Applicative'-based answer, but unlike 'Optics.Traversal.traverseOf' do not
    -- construct a new structure. 'traverseOf_' generalizes
    -- 'Data.Foldable.traverse_' to work over any 'Fold'.
    --
    -- >>> traverseOf_ each putStrLn ("hello","world")
    -- hello
    -- world
    --
    -- @
    -- 'Data.Foldable.traverse_' ≡ 'traverseOf_' 'folded'
    -- @
    traverseOf_
      :: (Is k A_Fold, Applicative f)
      => Optic' k is s a
      -> (a -> f r) -> s -> f ()
    traverseOf_ :: forall k (f :: * -> *) (is :: IxList) s a r.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s a -> (a -> f r) -> s -> f ()
    traverseOf_ Optic' k is s a
    o = \a -> f r
    f -> Traversed f r -> f ()
    forall (f :: * -> *) a. Functor f => Traversed f a -> f ()
    runTraversed (Traversed f r -> f ()) -> (s -> Traversed f r) -> s -> f ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optic' k is s a -> (a -> Traversed f r) -> s -> Traversed f r
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o (f r -> Traversed f r
    forall (f :: * -> *) a. f a -> Traversed f a
    Traversed (f r -> Traversed f r) -> (a -> f r) -> a -> Traversed f r
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. a -> f r
    f)
    {-# INLINE traverseOf_ #-}

    -- | A version of 'traverseOf_' with the arguments flipped.
    forOf_
      :: (Is k A_Fold, Applicative f)
      => Optic' k is s a
      -> s -> (a -> f r) -> f ()
    forOf_ :: forall k (f :: * -> *) (is :: IxList) s a r.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s a -> s -> (a -> f r) -> f ()
    forOf_ = ((a -> f r) -> s -> f ()) -> s -> (a -> f r) -> f ()
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (((a -> f r) -> s -> f ()) -> s -> (a -> f r) -> f ())
    -> (Optic' k is s a -> (a -> f r) -> s -> f ())
    -> Optic' k is s a
    -> s
    -> (a -> f r)
    -> f ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optic' k is s a -> (a -> f r) -> s -> f ()
    forall k (f :: * -> *) (is :: IxList) s a r.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s a -> (a -> f r) -> s -> f ()
    traverseOf_
    {-# INLINE forOf_ #-}

    -- | Evaluate each action in a structure observed by a 'Fold' from left to
    -- right, ignoring the results.
    --
    -- @
    -- 'sequenceA_' ≡ 'sequenceOf_' 'folded'
    -- @
    --
    -- >>> sequenceOf_ each (putStrLn "hello",putStrLn "world")
    -- hello
    -- world
    sequenceOf_
      :: (Is k A_Fold, Applicative f)
      => Optic' k is s (f a)
      -> s -> f ()
    sequenceOf_ :: forall k (f :: * -> *) (is :: IxList) s a.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s (f a) -> s -> f ()
    sequenceOf_ Optic' k is s (f a)
    o = Traversed f a -> f ()
    forall (f :: * -> *) a. Functor f => Traversed f a -> f ()
    runTraversed (Traversed f a -> f ()) -> (s -> Traversed f a) -> s -> f ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optic' k is s (f a) -> (f a -> Traversed f a) -> s -> Traversed f a
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s (f a)
    o f a -> Traversed f a
    forall (f :: * -> *) a. f a -> Traversed f a
    Traversed
    {-# INLINE sequenceOf_ #-}

    ----------------------------------------

    -- | Fold via the 'Foldable' class.
    folded :: Foldable f => Fold (f a) a
    folded :: forall (f :: * -> *) a. Foldable f => Fold (f a) a
    folded = (forall (p :: * -> * -> * -> *) i.
     Profunctor p =>
     Optic_ A_Fold p i (Curry NoIx i) (f a) (f a) a a)
    -> Optic A_Fold NoIx (f a) (f a) a a
    forall k (is :: IxList) s t a b.
    (forall (p :: * -> * -> * -> *) i.
     Profunctor p =>
     Optic_ k p i (Curry is i) s t a b)
    -> Optic k is s t a b
    Optic Optic__ p i i (f a) (f a) a a
    p i a a -> p (Curry NoIx i) (f a) (f a)
    forall (p :: * -> * -> * -> *) i.
    Profunctor p =>
    Optic_ A_Fold p i (Curry NoIx i) (f a) (f a) a a
    forall (p :: * -> * -> * -> *) (f :: * -> *) i a b.
    (Bicontravariant p, Traversing p, Foldable f) =>
    Optic__ p i i (f a) (f b) a b
    folded__
    {-# INLINE folded #-}

    -- | Obtain a 'Fold' by lifting an operation that returns a 'Foldable' result.
    --
    -- This can be useful to lift operations from @Data.List@ and elsewhere into a
    -- 'Fold'.
    --
    -- >>> toListOf (folding tail) [1,2,3,4]
    -- [2,3,4]
    folding :: Foldable f => (s -> f a) -> Fold s a
    folding :: forall (f :: * -> *) s a. Foldable f => (s -> f a) -> Fold s a
    folding s -> f a
    f = (forall (p :: * -> * -> * -> *) i.
     Profunctor p =>
     Optic_ A_Fold p i (Curry NoIx i) s s a a)
    -> Optic A_Fold NoIx s s a a
    forall k (is :: IxList) s t a b.
    (forall (p :: * -> * -> * -> *) i.
     Profunctor p =>
     Optic_ k p i (Curry is i) s t a b)
    -> Optic k is s t a b
    Optic ((s -> f a) -> p i (f a) s -> p i s s
    forall b a i c. (b -> a) -> p i a c -> p i b c
    forall (p :: * -> * -> * -> *) b a i c.
    Bicontravariant p =>
    (b -> a) -> p i a c -> p i b c
    contrafirst s -> f a
    f (p i (f a) s -> p i s s)
    -> (p i a a -> p i (f a) s) -> p i a a -> p i s s
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (forall (f :: * -> *).
     Applicative f =>
     (a -> f (ZonkAny 0)) -> f a -> f ())
    -> p i a a -> p i (f a) s
    forall (p :: * -> * -> * -> *) a u s v i t b.
    (Bicontravariant p, Traversing p) =>
    (forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v)
    -> Optic__ p i i s t a b
    foldVL__ (a -> f (ZonkAny 0)) -> f a -> f ()
    forall (f :: * -> *).
    Applicative f =>
    (a -> f (ZonkAny 0)) -> f a -> f ()
    forall (t :: * -> *) (f :: * -> *) a b.
    (Foldable t, Applicative f) =>
    (a -> f b) -> t a -> f ()
    traverse_)
    {-# INLINE folding #-}

    -- | Obtain a 'Fold' by lifting 'foldr' like function.
    --
    -- >>> toListOf (foldring foldr) [1,2,3,4]
    -- [1,2,3,4]
    foldring
      :: (forall f. Applicative f => (a -> f u -> f u) -> f v -> s -> f w)
      -> Fold s a
    foldring :: forall a u v s w.
    (forall (f :: * -> *).
     Applicative f =>
     (a -> f u -> f u) -> f v -> s -> f w)
    -> Fold s a
    foldring forall (f :: * -> *).
    Applicative f =>
    (a -> f u -> f u) -> f v -> s -> f w
    fr = (forall (p :: * -> * -> * -> *) i.
     Profunctor p =>
     Optic_ A_Fold p i (Curry NoIx i) s s a a)
    -> Optic A_Fold NoIx s s a a
    forall k (is :: IxList) s t a b.
    (forall (p :: * -> * -> * -> *) i.
     Profunctor p =>
     Optic_ k p i (Curry is i) s t a b)
    -> Optic k is s t a b
    Optic ((forall (f :: * -> *).
     Applicative f =>
     (a -> f u -> f u) -> f v -> s -> f w)
    -> Optic__ p i i s s a a
    forall (p :: * -> * -> * -> *) a u v s w i t b.
    (Bicontravariant p, Traversing p) =>
    (forall (f :: * -> *).
     Applicative f =>
     (a -> f u -> f u) -> f v -> s -> f w)
    -> Optic__ p i i s t a b
    foldring__ (a -> f u -> f u) -> f v -> s -> f w
    forall (f :: * -> *).
    Applicative f =>
    (a -> f u -> f u) -> f v -> s -> f w
    fr)
    {-# INLINE foldring #-}

    -- | Build a 'Fold' that unfolds its values from a seed.
    --
    -- @
    -- 'Prelude.unfoldr' ≡ 'toListOf' '.' 'unfolded'
    -- @
    --
    -- >>> toListOf (unfolded $ \b -> if b == 0 then Nothing else Just (b, b - 1)) 10
    -- [10,9,8,7,6,5,4,3,2,1]
    unfolded :: (s -> Maybe (a, s)) -> Fold s a
    unfolded :: forall s a. (s -> Maybe (a, s)) -> Fold s a
    unfolded s -> Maybe (a, s)
    step = (forall (f :: * -> *).
     Applicative f =>
     (a -> f (ZonkAny 2)) -> s -> f ())
    -> Fold s a
    forall a u s v.
    (forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v)
    -> Fold s a
    foldVL ((forall (f :: * -> *).
      Applicative f =>
      (a -> f (ZonkAny 2)) -> s -> f ())
     -> Fold s a)
    -> (forall (f :: * -> *).
        Applicative f =>
        (a -> f (ZonkAny 2)) -> s -> f ())
    -> Fold s a
    forall a b. (a -> b) -> a -> b
    $ \a -> f (ZonkAny 2)
    f -> ((s -> f ()) -> s -> f ()) -> s -> f ()
    forall a. (a -> a) -> a
    fix (((s -> f ()) -> s -> f ()) -> s -> f ())
    -> ((s -> f ()) -> s -> f ()) -> s -> f ()
    forall a b. (a -> b) -> a -> b
    $ \s -> f ()
    loop s
    b ->
      case s -> Maybe (a, s)
    step s
    b of
        Just (a
    a, s
    b') -> a -> f (ZonkAny 2)
    f a
    a f (ZonkAny 2) -> f () -> f ()
    forall a b. f a -> f b -> f b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> s -> f ()
    loop s
    b'
        Maybe (a, s)
    Nothing      -> () -> f ()
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()
    {-# INLINE unfolded #-}

    -- | Convert a fold to an 'AffineFold' that visits the first element of the
    -- original fold.
    --
    -- For the traversal version see 'Optics.Traversal.singular'.
    pre :: Is k A_Fold => Optic' k is s a -> AffineFold s a
    pre :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> AffineFold s a
    pre = (s -> Maybe a) -> AffineFold s a
    forall s a. (s -> Maybe a) -> AffineFold s a
    afolding ((s -> Maybe a) -> AffineFold s a)
    -> (Optic' k is s a -> s -> Maybe a)
    -> Optic' k is s a
    -> AffineFold s a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optic' k is s a -> s -> Maybe a
    forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> s -> Maybe a
    headOf
    {-# INLINE pre #-}

    -- | This allows you to traverse the elements of a 'Fold' in the opposite order.
    backwards_
      :: Is k A_Fold
      => Optic' k is s a
      -> Fold s a
    backwards_ :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> Fold s a
    backwards_ Optic' k is s a
    o = (forall (f :: * -> *).
     Applicative f =>
     (a -> f (ZonkAny 3)) -> s -> f ())
    -> Fold s a
    forall a u s v.
    (forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v)
    -> Fold s a
    foldVL ((forall (f :: * -> *).
      Applicative f =>
      (a -> f (ZonkAny 3)) -> s -> f ())
     -> Fold s a)
    -> (forall (f :: * -> *).
        Applicative f =>
        (a -> f (ZonkAny 3)) -> s -> f ())
    -> Fold s a
    forall a b. (a -> b) -> a -> b
    $ \a -> f (ZonkAny 3)
    f -> Backwards f () -> f ()
    forall {k} (f :: k -> *) (a :: k). Backwards f a -> f a
    forwards (Backwards f () -> f ()) -> (s -> Backwards f ()) -> s -> f ()
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. Optic' k is s a
    -> (a -> Backwards f (ZonkAny 3)) -> s -> Backwards f ()
    forall k (f :: * -> *) (is :: IxList) s a r.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s a -> (a -> f r) -> s -> f ()
    traverseOf_ Optic' k is s a
    o (f (ZonkAny 3) -> Backwards f (ZonkAny 3)
    forall {k} (f :: k -> *) (a :: k). f a -> Backwards f a
    Backwards (f (ZonkAny 3) -> Backwards f (ZonkAny 3))
    -> (a -> f (ZonkAny 3)) -> a -> Backwards f (ZonkAny 3)
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. a -> f (ZonkAny 3)
    f)
    {-# INLINE backwards_ #-}

    -- | Return entries of the first 'Fold', then the second one.
    --
    -- >>> toListOf (_1 % ix 0 `summing` _2 % ix 1) ([1,2], [4,7,1])
    -- [1,7]
    --
    -- For the traversal version see 'Optics.Traversal.adjoin'.
    summing
      :: (Is k A_Fold, Is l A_Fold)
      => Optic' k is s a
      -> Optic' l js s a
      -> Fold s a
    summing :: forall k l (is :: IxList) s a (js :: IxList).
    (Is k A_Fold, Is l A_Fold) =>
    Optic' k is s a -> Optic' l js s a -> Fold s a
    summing Optic' k is s a
    a Optic' l js s a
    b = (forall (f :: * -> *).
     Applicative f =>
     (a -> f (ZonkAny 4)) -> s -> f ())
    -> Fold s a
    forall a u s v.
    (forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v)
    -> Fold s a
    foldVL ((forall (f :: * -> *).
      Applicative f =>
      (a -> f (ZonkAny 4)) -> s -> f ())
     -> Fold s a)
    -> (forall (f :: * -> *).
        Applicative f =>
        (a -> f (ZonkAny 4)) -> s -> f ())
    -> Fold s a
    forall a b. (a -> b) -> a -> b
    $ \a -> f (ZonkAny 4)
    f s
    s -> Optic' k is s a -> (a -> f (ZonkAny 4)) -> s -> f ()
    forall k (f :: * -> *) (is :: IxList) s a r.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s a -> (a -> f r) -> s -> f ()
    traverseOf_ Optic' k is s a
    a a -> f (ZonkAny 4)
    f s
    s f () -> f () -> f ()
    forall a b. f a -> f b -> f b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> Optic' l js s a -> (a -> f (ZonkAny 4)) -> s -> f ()
    forall k (f :: * -> *) (is :: IxList) s a r.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s a -> (a -> f r) -> s -> f ()
    traverseOf_ Optic' l js s a
    b a -> f (ZonkAny 4)
    f s
    s
    infixr 6 `summing` -- Same as (<>)
    {-# INLINE summing #-}

    -- | Try the first 'Fold'. If it returns no entries, try the second one.
    --
    -- >>> toListOf (ix 1 `failing` ix 0) [4,7]
    -- [7]
    -- >>> toListOf (ix 1 `failing` ix 0) [4]
    -- [4]
    --
    failing
      :: (Is k A_Fold, Is l A_Fold)
      => Optic' k is s a
      -> Optic' l js s a
      -> Fold s a
    failing :: forall k l (is :: IxList) s a (js :: IxList).
    (Is k A_Fold, Is l A_Fold) =>
    Optic' k is s a -> Optic' l js s a -> Fold s a
    failing Optic' k is s a
    a Optic' l js s a
    b = (forall (f :: * -> *).
     Applicative f =>
     (a -> f (ZonkAny 5)) -> s -> f ())
    -> Fold s a
    forall a u s v.
    (forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v)
    -> Fold s a
    foldVL ((forall (f :: * -> *).
      Applicative f =>
      (a -> f (ZonkAny 5)) -> s -> f ())
     -> Fold s a)
    -> (forall (f :: * -> *).
        Applicative f =>
        (a -> f (ZonkAny 5)) -> s -> f ())
    -> Fold s a
    forall a b. (a -> b) -> a -> b
    $ \a -> f (ZonkAny 5)
    f s
    s ->
      let OrT Bool
    visited f ()
    fu = Optic' k is s a -> (a -> OrT f (ZonkAny 5)) -> s -> OrT f ()
    forall k (f :: * -> *) (is :: IxList) s a r.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s a -> (a -> f r) -> s -> f ()
    traverseOf_ Optic' k is s a
    a (f (ZonkAny 5) -> OrT f (ZonkAny 5)
    forall (f :: * -> *) a. f a -> OrT f a
    wrapOrT (f (ZonkAny 5) -> OrT f (ZonkAny 5))
    -> (a -> f (ZonkAny 5)) -> a -> OrT f (ZonkAny 5)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> f (ZonkAny 5)
    f) s
    s
      in if Bool
    visited
         then f ()
    fu
         else Optic' l js s a -> (a -> f (ZonkAny 5)) -> s -> f ()
    forall k (f :: * -> *) (is :: IxList) s a r.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s a -> (a -> f r) -> s -> f ()
    traverseOf_ Optic' l js s a
    b a -> f (ZonkAny 5)
    f s
    s
    infixl 3 `failing` -- Same as (<|>)
    {-# INLINE failing #-}

    ----------------------------------------
    -- Special folds

    -- | Check to see if this optic matches 1 or more entries.
    --
    -- >>> has _Left (Left 12)
    -- True
    --
    -- >>> has _Right (Left 12)
    -- False
    --
    -- This will always return 'True' for a 'Optics.Lens.Lens' or
    -- 'Optics.Getter.Getter'.
    --
    -- >>> has _1 ("hello","world")
    -- True
    has :: Is k A_Fold => Optic' k is s a -> s -> Bool
    has :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> s -> Bool
    has Optic' k is s a
    o = Any -> Bool
    getAny (Any -> Bool) -> (s -> Any) -> s -> Bool
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. Optic' k is s a -> (a -> Any) -> s -> Any
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o (\a
    _ -> Bool -> Any
    Any Bool
    True)
    {-# INLINE has #-}

    -- | Check to see if this 'Fold' or 'Optics.Traversal.Traversal' has
    -- no matches.
    --
    -- >>> hasn't _Left (Right 12)
    -- True
    --
    -- >>> hasn't _Left (Left 12)
    -- False
    hasn't :: Is k A_Fold => Optic' k is s a -> s -> Bool
    hasn't :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> s -> Bool
    hasn't Optic' k is s a
    o = All -> Bool
    getAll (All -> Bool) -> (s -> All) -> s -> Bool
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. Optic' k is s a -> (a -> All) -> s -> All
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o (\a
    _ -> Bool -> All
    All Bool
    False)
    {-# INLINE hasn't #-}

    -- | Retrieve the first entry of a 'Fold'.
    --
    -- >>> headOf folded [1..10]
    -- Just 1
    --
    -- >>> headOf each (1,2)
    -- Just 1
    headOf :: Is k A_Fold => Optic' k is s a -> s -> Maybe a
    headOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> s -> Maybe a
    headOf Optic' k is s a
    o = Leftmost a -> Maybe a
    forall a. Leftmost a -> Maybe a
    getLeftmost (Leftmost a -> Maybe a) -> (s -> Leftmost a) -> s -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optic' k is s a -> (a -> Leftmost a) -> s -> Leftmost a
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o a -> Leftmost a
    forall a. a -> Leftmost a
    LLeaf
    {-# INLINE headOf #-}

    -- | Retrieve the last entry of a 'Fold'.
    --
    -- >>> lastOf folded [1..10]
    -- Just 10
    --
    -- >>> lastOf each (1,2)
    -- Just 2
    lastOf :: Is k A_Fold => Optic' k is s a -> s -> Maybe a
    lastOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> s -> Maybe a
    lastOf Optic' k is s a
    o = Rightmost a -> Maybe a
    forall a. Rightmost a -> Maybe a
    getRightmost (Rightmost a -> Maybe a) -> (s -> Rightmost a) -> s -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optic' k is s a -> (a -> Rightmost a) -> s -> Rightmost a
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o a -> Rightmost a
    forall a. a -> Rightmost a
    RLeaf
    {-# INLINE lastOf #-}

    -- | Returns 'True' if every target of a 'Fold' is 'True'.
    --
    -- >>> andOf each (True, False)
    -- False
    -- >>> andOf each (True, True)
    -- True
    --
    -- @
    -- 'Data.Foldable.and' ≡ 'andOf' 'folded'
    -- @
    andOf :: Is k A_Fold => Optic' k is s Bool -> s -> Bool
    andOf :: forall k (is :: IxList) s.
    Is k A_Fold =>
    Optic' k is s Bool -> s -> Bool
    andOf Optic' k is s Bool
    o = All -> Bool
    getAll (All -> Bool) -> (s -> All) -> s -> Bool
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. Optic' k is s Bool -> (Bool -> All) -> s -> All
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s Bool
    o Bool -> All
    All
    {-# INLINE andOf #-}

    -- | Returns 'True' if any target of a 'Fold' is 'True'.
    --
    -- >>> orOf each (True, False)
    -- True
    -- >>> orOf each (False, False)
    -- False
    --
    -- @
    -- 'Data.Foldable.or' ≡ 'orOf' 'folded'
    -- @
    orOf :: Is k A_Fold => Optic' k is s Bool -> s -> Bool
    orOf :: forall k (is :: IxList) s.
    Is k A_Fold =>
    Optic' k is s Bool -> s -> Bool
    orOf Optic' k is s Bool
    o = Any -> Bool
    getAny (Any -> Bool) -> (s -> Any) -> s -> Bool
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. Optic' k is s Bool -> (Bool -> Any) -> s -> Any
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s Bool
    o Bool -> Any
    Any
    {-# INLINE orOf #-}

    -- | Returns 'True' if any target of a 'Fold' satisfies a predicate.
    --
    -- >>> anyOf each (=='x') ('x','y')
    -- True
    anyOf :: Is k A_Fold => Optic' k is s a -> (a -> Bool) -> s -> Bool
    anyOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> (a -> Bool) -> s -> Bool
    anyOf Optic' k is s a
    o = \a -> Bool
    f -> Any -> Bool
    getAny (Any -> Bool) -> (s -> Any) -> s -> Bool
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. Optic' k is s a -> (a -> Any) -> s -> Any
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o (Bool -> Any
    Any (Bool -> Any) -> (a -> Bool) -> a -> Any
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. a -> Bool
    f)
    {-# INLINE anyOf #-}

    -- | Returns 'True' if every target of a 'Fold' satisfies a predicate.
    --
    -- >>> allOf each (>=3) (4,5)
    -- True
    -- >>> allOf folded (>=2) [1..10]
    -- False
    --
    -- @
    -- 'Data.Foldable.all' ≡ 'allOf' 'folded'
    -- @
    allOf :: Is k A_Fold => Optic' k is s a -> (a -> Bool) -> s -> Bool
    allOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> (a -> Bool) -> s -> Bool
    allOf Optic' k is s a
    o = \a -> Bool
    f -> All -> Bool
    getAll (All -> Bool) -> (s -> All) -> s -> Bool
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. Optic' k is s a -> (a -> All) -> s -> All
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is s a
    o (Bool -> All
    All (Bool -> All) -> (a -> Bool) -> a -> All
    forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
    #. a -> Bool
    f)
    {-# INLINE allOf #-}

    -- | Returns 'True' only if no targets of a 'Fold' satisfy a predicate.
    --
    -- >>> noneOf each (not . isn't _Nothing) (Just 3, Just 4, Just 5)
    -- True
    -- >>> noneOf (folded % folded) (<10) [[13,99,20],[3,71,42]]
    -- False
    noneOf :: Is k A_Fold => Optic' k is s a -> (a -> Bool) -> s -> Bool
    noneOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> (a -> Bool) -> s -> Bool
    noneOf Optic' k is s a
    o = \a -> Bool
    f -> Bool -> Bool
    not (Bool -> Bool) -> (s -> Bool) -> s -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optic' k is s a -> (a -> Bool) -> s -> Bool
    forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> (a -> Bool) -> s -> Bool
    anyOf Optic' k is s a
    o a -> Bool
    f
    {-# INLINE noneOf #-}

    -- | Calculate the 'Product' of every number targeted by a 'Fold'.
    --
    -- >>> productOf each (4,5)
    -- 20
    -- >>> productOf folded [1,2,3,4,5]
    -- 120
    --
    -- @
    -- 'Data.Foldable.product' ≡ 'productOf' 'folded'
    -- @
    --
    -- This operation may be more strict than you would expect. If you want a lazier
    -- version use @\\o -> 'getProduct' '.' 'foldMapOf' o 'Product'@.
    productOf :: (Is k A_Fold, Num a) => Optic' k is s a -> s -> a
    productOf :: forall k a (is :: IxList) s.
    (Is k A_Fold, Num a) =>
    Optic' k is s a -> s -> a
    productOf Optic' k is s a
    o = Optic' k is s a -> (a -> a -> a) -> a -> s -> a
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (r -> a -> r) -> r -> s -> r
    foldlOf' Optic' k is s a
    o a -> a -> a
    forall a. Num a => a -> a -> a
    (*) a
    1
    {-# INLINE productOf #-}

    -- | Calculate the 'Sum' of every number targeted by a 'Fold'.
    --
    -- >>> sumOf each (5,6)
    -- 11
    -- >>> sumOf folded [1,2,3,4]
    -- 10
    -- >>> sumOf (folded % each) [(1,2),(3,4)]
    -- 10
    --
    -- @
    -- 'Data.Foldable.sum' ≡ 'sumOf' 'folded'
    -- @
    --
    -- This operation may be more strict than you would expect. If you want a lazier
    -- version use @\\o -> 'getSum' '.' 'foldMapOf' o 'Sum'@
    sumOf :: (Is k A_Fold, Num a) => Optic' k is s a -> s -> a
    sumOf :: forall k a (is :: IxList) s.
    (Is k A_Fold, Num a) =>
    Optic' k is s a -> s -> a
    sumOf Optic' k is s a
    o = Optic' k is s a -> (a -> a -> a) -> a -> s -> a
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (r -> a -> r) -> r -> s -> r
    foldlOf' Optic' k is s a
    o a -> a -> a
    forall a. Num a => a -> a -> a
    (+) a
    0
    {-# INLINE sumOf #-}

    -- | The sum of a collection of actions.
    --
    -- >>> asumOf each ("hello","world")
    -- "helloworld"
    --
    -- >>> asumOf each (Nothing, Just "hello", Nothing)
    -- Just "hello"
    --
    -- @
    -- 'asum' ≡ 'asumOf' 'folded'
    -- @
    asumOf :: (Is k A_Fold, Alternative f) => Optic' k is s (f a) -> s -> f a
    asumOf :: forall k (f :: * -> *) (is :: IxList) s a.
    (Is k A_Fold, Alternative f) =>
    Optic' k is s (f a) -> s -> f a
    asumOf Optic' k is s (f a)
    o = Optic' k is s (f a) -> (f a -> f a -> f a) -> f a -> s -> f a
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (a -> r -> r) -> r -> s -> r
    foldrOf Optic' k is s (f a)
    o f a -> f a -> f a
    forall a. f a -> f a -> f a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    (<|>) f a
    forall a. f a
    forall (f :: * -> *) a. Alternative f => f a
    empty
    {-# INLINE asumOf #-}

    -- | The sum of a collection of actions.
    --
    -- >>> msumOf each ("hello","world")
    -- "helloworld"
    --
    -- >>> msumOf each (Nothing, Just "hello", Nothing)
    -- Just "hello"
    --
    -- @
    -- 'msum' ≡ 'msumOf' 'folded'
    -- @
    msumOf :: (Is k A_Fold, MonadPlus m) => Optic' k is s (m a) -> s -> m a
    msumOf :: forall k (m :: * -> *) (is :: IxList) s a.
    (Is k A_Fold, MonadPlus m) =>
    Optic' k is s (m a) -> s -> m a
    msumOf Optic' k is s (m a)
    o = Optic' k is s (m a) -> (m a -> m a -> m a) -> m a -> s -> m a
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (a -> r -> r) -> r -> s -> r
    foldrOf Optic' k is s (m a)
    o m a -> m a -> m a
    forall a. m a -> m a -> m a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    mplus m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero
    {-# INLINE msumOf #-}

    -- | Does the element occur anywhere within a given 'Fold' of the structure?
    --
    -- >>> elemOf each "hello" ("hello","world")
    -- True
    --
    -- @
    -- 'elem' ≡ 'elemOf' 'folded'
    -- @
    elemOf :: (Is k A_Fold, Eq a) => Optic' k is s a -> a -> s -> Bool
    elemOf :: forall k a (is :: IxList) s.
    (Is k A_Fold, Eq a) =>
    Optic' k is s a -> a -> s -> Bool
    elemOf Optic' k is s a
    o = Optic' k is s a -> (a -> Bool) -> s -> Bool
    forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> (a -> Bool) -> s -> Bool
    anyOf Optic' k is s a
    o ((a -> Bool) -> s -> Bool) -> (a -> a -> Bool) -> a -> s -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    {-# INLINE elemOf #-}

    -- | Does the element not occur anywhere within a given 'Fold' of the structure?
    --
    -- >>> notElemOf each 'd' ('a','b','c')
    -- True
    --
    -- >>> notElemOf each 'a' ('a','b','c')
    -- False
    --
    -- @
    -- 'notElem' ≡ 'notElemOf' 'folded'
    -- @
    notElemOf :: (Is k A_Fold, Eq a) => Optic' k is s a -> a -> s -> Bool
    notElemOf :: forall k a (is :: IxList) s.
    (Is k A_Fold, Eq a) =>
    Optic' k is s a -> a -> s -> Bool
    notElemOf Optic' k is s a
    o = Optic' k is s a -> (a -> Bool) -> s -> Bool
    forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> (a -> Bool) -> s -> Bool
    allOf Optic' k is s a
    o ((a -> Bool) -> s -> Bool) -> (a -> a -> Bool) -> a -> s -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    (/=)
    {-# INLINE notElemOf #-}

    -- | Calculate the number of targets there are for a 'Fold' in a given
    -- container.
    --
    -- /Note:/ This can be rather inefficient for large containers and just like
    -- 'length', this will not terminate for infinite folds.
    --
    -- @
    -- 'length' ≡ 'lengthOf' 'folded'
    -- @
    --
    -- >>> lengthOf _1 ("hello",())
    -- 1
    --
    -- >>> lengthOf folded [1..10]
    -- 10
    --
    -- >>> lengthOf (folded % folded) [[1,2],[3,4],[5,6]]
    -- 6
    lengthOf :: Is k A_Fold => Optic' k is s a -> s -> Int
    lengthOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> s -> Int
    lengthOf Optic' k is s a
    o = Optic' k is s a -> (Int -> a -> Int) -> Int -> s -> Int
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (r -> a -> r) -> r -> s -> r
    foldlOf' Optic' k is s a
    o (\ Int
    n a
    _ -> Int
    1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    n) Int
    0
    {-# INLINE lengthOf #-}

    -- | Obtain the maximum element (if any) targeted by a 'Fold' safely.
    --
    -- Note: 'maximumOf' on a valid 'Optics.Iso.Iso', 'Optics.Lens.Lens'
    -- or 'Optics.Getter.Getter' will always return 'Just' a value.
    --
    -- >>> maximumOf folded [1..10]
    -- Just 10
    --
    -- >>> maximumOf folded []
    -- Nothing
    --
    -- >>> maximumOf (folded % filtered even) [1,4,3,6,7,9,2]
    -- Just 6
    --
    -- @
    -- 'maximum' ≡ 'Data.Maybe.fromMaybe' ('error' \"empty\") '.' 'maximumOf' 'folded'
    -- @
    --
    -- In the interest of efficiency, This operation has semantics more strict than
    -- strictly necessary.  @\\o -> 'Data.Semigroup.getMax' . 'foldMapOf' o 'Data.Semigroup.Max'@ has lazier
    -- semantics but could leak memory.
    maximumOf :: (Is k A_Fold, Ord a) => Optic' k is s a -> s -> Maybe a
    maximumOf :: forall k a (is :: IxList) s.
    (Is k A_Fold, Ord a) =>
    Optic' k is s a -> s -> Maybe a
    maximumOf Optic' k is s a
    o = Optic' k is s a
    -> (Maybe a -> a -> Maybe a) -> Maybe a -> s -> Maybe a
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (r -> a -> r) -> r -> s -> r
    foldlOf' Optic' k is s a
    o Maybe a -> a -> Maybe a
    forall {a}. Ord a => Maybe a -> a -> Maybe a
    mf Maybe a
    forall a. Maybe a
    Nothing where
      mf :: Maybe a -> a -> Maybe a
    mf Maybe a
    Nothing a
    y  = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! a
    y
      mf (Just a
    x) a
    y = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! a -> a -> a
    forall a. Ord a => a -> a -> a
    max a
    x a
    y
    {-# INLINE maximumOf #-}

    -- | Obtain the minimum element (if any) targeted by a 'Fold' safely.
    --
    -- Note: 'minimumOf' on a valid 'Optics.Iso.Iso', 'Optics.Lens.Lens'
    -- or 'Optics.Getter.Getter' will always return 'Just' a value.
    --
    -- >>> minimumOf folded [1..10]
    -- Just 1
    --
    -- >>> minimumOf folded []
    -- Nothing
    --
    -- >>> minimumOf (folded % filtered even) [1,4,3,6,7,9,2]
    -- Just 2
    --
    -- @
    -- 'minimum' ≡ 'Data.Maybe.fromMaybe' ('error' \"empty\") '.' 'minimumOf' 'folded'
    -- @
    --
    -- In the interest of efficiency, This operation has semantics more strict than
    -- strictly necessary.  @\\o -> 'Data.Semigroup.getMin' . 'foldMapOf' o 'Data.Semigroup.Min'@ has lazier
    -- semantics but could leak memory.
    minimumOf :: (Is k A_Fold, Ord a) => Optic' k is s a -> s -> Maybe a
    minimumOf :: forall k a (is :: IxList) s.
    (Is k A_Fold, Ord a) =>
    Optic' k is s a -> s -> Maybe a
    minimumOf Optic' k is s a
    o = Optic' k is s a
    -> (Maybe a -> a -> Maybe a) -> Maybe a -> s -> Maybe a
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (r -> a -> r) -> r -> s -> r
    foldlOf' Optic' k is s a
    o Maybe a -> a -> Maybe a
    forall {a}. Ord a => Maybe a -> a -> Maybe a
    mf Maybe a
    forall a. Maybe a
    Nothing where
      mf :: Maybe a -> a -> Maybe a
    mf Maybe a
    Nothing a
    y = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! a
    y
      mf (Just a
    x) a
    y = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! a -> a -> a
    forall a. Ord a => a -> a -> a
    min a
    x a
    y
    {-# INLINE minimumOf #-}

    -- | Obtain the maximum element (if any) targeted by a 'Fold' according to a
    -- user supplied 'Ordering'.
    --
    -- >>> maximumByOf folded (compare `on` length) ["mustard","relish","ham"]
    -- Just "mustard"
    --
    -- In the interest of efficiency, This operation has semantics more strict than
    -- strictly necessary.
    --
    -- @
    -- 'Data.Foldable.maximumBy' cmp ≡ 'Data.Maybe.fromMaybe' ('error' \"empty\") '.' 'maximumByOf' 'folded' cmp
    -- @
    maximumByOf :: Is k A_Fold => Optic' k is s a -> (a -> a -> Ordering) -> s -> Maybe a
    maximumByOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> (a -> a -> Ordering) -> s -> Maybe a
    maximumByOf Optic' k is s a
    o = \a -> a -> Ordering
    cmp ->
      let mf :: Maybe a -> a -> Maybe a
    mf Maybe a
    Nothing a
    y  = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! a
    y
          mf (Just a
    x) a
    y = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! if a -> a -> Ordering
    cmp a
    x a
    y Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    == Ordering
    GT then a
    x else a
    y
      in Optic' k is s a
    -> (Maybe a -> a -> Maybe a) -> Maybe a -> s -> Maybe a
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (r -> a -> r) -> r -> s -> r
    foldlOf' Optic' k is s a
    o Maybe a -> a -> Maybe a
    mf Maybe a
    forall a. Maybe a
    Nothing
    {-# INLINE maximumByOf #-}

    -- | Obtain the minimum element (if any) targeted by a 'Fold' according to a
    -- user supplied 'Ordering'.
    --
    -- In the interest of efficiency, This operation has semantics more strict than
    -- strictly necessary.
    --
    -- >>> minimumByOf folded (compare `on` length) ["mustard","relish","ham"]
    -- Just "ham"
    --
    -- @
    -- 'minimumBy' cmp ≡ 'Data.Maybe.fromMaybe' ('error' \"empty\") '.' 'minimumByOf' 'folded' cmp
    -- @
    minimumByOf :: Is k A_Fold => Optic' k is s a -> (a -> a -> Ordering) -> s -> Maybe a
    minimumByOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> (a -> a -> Ordering) -> s -> Maybe a
    minimumByOf Optic' k is s a
    o = \a -> a -> Ordering
    cmp ->
      let mf :: Maybe a -> a -> Maybe a
    mf Maybe a
    Nothing a
    y  = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! a
    y
          mf (Just a
    x) a
    y = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! if a -> a -> Ordering
    cmp a
    x a
    y Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    == Ordering
    GT then a
    y else a
    x
      in Optic' k is s a
    -> (Maybe a -> a -> Maybe a) -> Maybe a -> s -> Maybe a
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (r -> a -> r) -> r -> s -> r
    foldlOf' Optic' k is s a
    o Maybe a -> a -> Maybe a
    mf Maybe a
    forall a. Maybe a
    Nothing
    {-# INLINE minimumByOf #-}

    -- | The 'findOf' function takes a 'Fold', a predicate and a structure and
    -- returns the leftmost element of the structure matching the predicate, or
    -- 'Nothing' if there is no such element.
    --
    -- >>> findOf each even (1,3,4,6)
    -- Just 4
    --
    -- >>> findOf folded even [1,3,5,7]
    -- Nothing
    --
    -- @
    -- 'Data.Foldable.find' ≡ 'findOf' 'folded'
    -- @
    findOf :: Is k A_Fold => Optic' k is s a -> (a -> Bool) -> s -> Maybe a
    findOf :: forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> (a -> Bool) -> s -> Maybe a
    findOf Optic' k is s a
    o = \a -> Bool
    f -> Optic' k is s a
    -> (a -> Maybe a -> Maybe a) -> Maybe a -> s -> Maybe a
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (a -> r -> r) -> r -> s -> r
    foldrOf Optic' k is s a
    o (\a
    a Maybe a
    y -> if a -> Bool
    f a
    a then a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a else Maybe a
    y) Maybe a
    forall a. Maybe a
    Nothing
    {-# INLINE findOf #-}

    -- | The 'findMOf' function takes a 'Fold', a monadic predicate and a structure
    -- and returns in the monad the leftmost element of the structure matching the
    -- predicate, or 'Nothing' if there is no such element.
    --
    -- >>> findMOf each (\x -> print ("Checking " ++ show x) >> return (even x)) (1,3,4,6)
    -- "Checking 1"
    -- "Checking 3"
    -- "Checking 4"
    -- Just 4
    --
    -- >>> findMOf each (\x -> print ("Checking " ++ show x) >> return (even x)) (1,3,5,7)
    -- "Checking 1"
    -- "Checking 3"
    -- "Checking 5"
    -- "Checking 7"
    -- Nothing
    --
    -- @
    -- 'findMOf' 'folded' :: (Monad m, Foldable f) => (a -> m Bool) -> f a -> m (Maybe a)
    -- @
    findMOf :: (Is k A_Fold, Monad m) => Optic' k is s a -> (a -> m Bool) -> s -> m (Maybe a)
    findMOf :: forall k (m :: * -> *) (is :: IxList) s a.
    (Is k A_Fold, Monad m) =>
    Optic' k is s a -> (a -> m Bool) -> s -> m (Maybe a)
    findMOf Optic' k is s a
    o = \a -> m Bool
    f -> Optic' k is s a
    -> (a -> m (Maybe a) -> m (Maybe a))
    -> m (Maybe a)
    -> s
    -> m (Maybe a)
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (a -> r -> r) -> r -> s -> r
    foldrOf Optic' k is s a
    o
      (\a
    a m (Maybe a)
    y -> a -> m Bool
    f a
    a m Bool -> (Bool -> m (Maybe a)) -> m (Maybe a)
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \Bool
    r -> if Bool
    r then Maybe a -> m (Maybe a)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a) else m (Maybe a)
    y)
      (Maybe a -> m (Maybe a)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe a
    forall a. Maybe a
    Nothing)
    {-# INLINE findMOf #-}

    -- | The 'lookupOf' function takes a 'Fold', a key, and a structure containing
    -- key/value pairs.  It returns the first value corresponding to the given
    -- key. This function generalizes 'lookup' to work on an arbitrary 'Fold'
    -- instead of lists.
    --
    -- >>> lookupOf folded 4 [(2, 'a'), (4, 'b'), (4, 'c')]
    -- Just 'b'
    --
    -- >>> lookupOf folded 2 [(2, 'a'), (4, 'b'), (4, 'c')]
    -- Just 'a'
    lookupOf :: (Is k A_Fold, Eq a) => Optic' k is s (a, v) -> a -> s -> Maybe v
    lookupOf :: forall k a (is :: IxList) s v.
    (Is k A_Fold, Eq a) =>
    Optic' k is s (a, v) -> a -> s -> Maybe v
    lookupOf Optic' k is s (a, v)
    o a
    a = Optic' k is s (a, v)
    -> ((a, v) -> Maybe v -> Maybe v) -> Maybe v -> s -> Maybe v
    forall k (is :: IxList) s a r.
    Is k A_Fold =>
    Optic' k is s a -> (a -> r -> r) -> r -> s -> r
    foldrOf Optic' k is s (a, v)
    o (\(a
    a', v
    v) Maybe v
    next -> if a
    a a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    a' then v -> Maybe v
    forall a. a -> Maybe a
    Just v
    v else Maybe v
    next) Maybe v
    forall a. Maybe a
    Nothing
    {-# INLINE lookupOf #-}

    -- | Given a 'Fold' that knows how to locate immediate children, retrieve all of
    -- the transitive descendants of a node, including itself.
    --
    -- @since 0.4.1
    universeOf :: Is k A_Fold => Optic' k is a a -> a -> [a]
    universeOf :: forall k (is :: IxList) a.
    Is k A_Fold =>
    Optic' k is a a -> a -> [a]
    universeOf Optic' k is a a
    o = (Endo [a] -> [a] -> [a]
    forall a. Endo a -> a -> a
    `appEndo` []) (Endo [a] -> [a]) -> (a -> Endo [a]) -> a -> [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Endo [a]
    go
      where
        go :: a -> Endo [a]
    go a
    a = ([a] -> [a]) -> Endo [a]
    forall a. (a -> a) -> Endo a
    Endo (a
    a a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :) Endo [a] -> Endo [a] -> Endo [a]
    forall a. Semigroup a => a -> a -> a
    <> Optic' k is a a -> (a -> Endo [a]) -> a -> Endo [a]
    forall k m (is :: IxList) s a.
    (Is k A_Fold, Monoid m) =>
    Optic' k is s a -> (a -> m) -> s -> m
    foldMapOf Optic' k is a a
    o a -> Endo [a]
    go a
    a
    {-# INLINE universeOf #-}

    -- | Given a 'Fold' that knows how to locate immediate children, fold all of the
    -- transitive descendants of a node, including itself.
    --
    -- @since 0.4.1
    cosmosOf :: forall k is a. Is k A_Fold => Optic' k is a a -> Fold a a
    cosmosOf :: forall k (is :: IxList) a.
    Is k A_Fold =>
    Optic' k is a a -> Fold a a
    cosmosOf Optic' k is a a
    o = (forall (f :: * -> *). Applicative f => (a -> f ()) -> a -> f ())
    -> Fold a a
    forall a u s v.
    (forall (f :: * -> *). Applicative f => (a -> f u) -> s -> f v)
    -> Fold s a
    foldVL (a -> f ()) -> a -> f ()
    forall (f :: * -> *). Applicative f => (a -> f ()) -> a -> f ()
    go
      where
        go :: Applicative f => (a -> f ()) -> a -> f ()
        go :: forall (f :: * -> *). Applicative f => (a -> f ()) -> a -> f ()
    go a -> f ()
    f a
    a = a -> f ()
    f a
    a f () -> f () -> f ()
    forall a b. f a -> f b -> f b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> Optic' k is a a -> (a -> f ()) -> a -> f ()
    forall k (f :: * -> *) (is :: IxList) s a r.
    (Is k A_Fold, Applicative f) =>
    Optic' k is s a -> (a -> f r) -> s -> f ()
    traverseOf_ Optic' k is a a
    o ((a -> f ()) -> a -> f ()
    forall (f :: * -> *). Applicative f => (a -> f ()) -> a -> f ()
    go a -> f ()
    f) a
    a
    {-# INLINE cosmosOf #-}

    -- | Perform a fold-like computation on each value, technically a paramorphism.
    --
    -- @since 0.4.1
    paraOf :: Is k A_Fold => Optic' k is a a -> (a -> [r] -> r) -> a -> r
    paraOf :: forall k (is :: IxList) a r.
    Is k A_Fold =>
    Optic' k is a a -> (a -> [r] -> r) -> a -> r
    paraOf Optic' k is a a
    o a -> [r] -> r
    f = a -> r
    go
      where
        go :: a -> r
    go a
    a = a -> [r] -> r
    f a
    a (a -> r
    go (a -> r) -> [a] -> [r]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Optic' k is a a -> a -> [a]
    forall k (is :: IxList) s a.
    Is k A_Fold =>
    Optic' k is s a -> s -> [a]
    toListOf Optic' k is a a
    o a
    a)
    {-# INLINE paraOf #-}

    -- $setup
    -- >>> import Optics.Core