{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
-- |
-- Module: Optics.IxFold
-- Description: An indexed version of a 'Optics.Fold.Fold'.
--
-- An 'IxFold' is an indexed version of a 'Optics.Fold.Fold'. 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.IxFold
  (
  -- * Formation
    IxFold

  -- * Introduction
  , ifoldVL

  -- * Elimination
  , ifoldMapOf
  , ifoldrOf
  , ifoldlOf'
  , itoListOf
  , itraverseOf_
  , iforOf_

  -- * Additional introduction forms
  , ifolded
  , ifolding
  , ifoldring

  -- * Additional elimination forms
  -- | See also 'Data.Map.Optics.toMapOf', which constructs a 'Data.Map.Map' from an 'IxFold'.
  , iheadOf
  , ilastOf
  , ianyOf
  , iallOf
  , inoneOf
  , ifindOf
  , ifindMOf

  -- * Combinators
  , ipre
  , ifiltered
  , ibackwards_

  -- * Monoid structures #monoids#
  -- | 'IxFold' admits (at least) two monoid structures:
  --
  -- * 'isumming' concatenates results from both folds.
  --
  -- * 'ifailing' 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 'IxFold', because there is
  -- not a unique choice of monoid to use, and the ('<>') operator could not be
  -- used to combine optics of different kinds.
  , isumming
  , ifailing

  -- * Subtyping
  , A_Fold

  -- * Re-exports
  , FoldableWithIndex(..)
  ) where

import Control.Applicative.Backwards
import Data.Monoid

import Data.Profunctor.Indexed

import Optics.Internal.Bi
import Optics.Internal.Indexed
import Optics.Internal.Indexed.Classes
import Optics.Internal.Fold
import Optics.Internal.IxFold
import Optics.Internal.Optic
import Optics.Internal.Utils
import Optics.IxAffineFold
import Optics.Fold

-- | Type synonym for an indexed fold.
type IxFold i s a = Optic' A_Fold (WithIx i) s a

-- | Obtain an indexed fold by lifting 'itraverse_' like function.
--
-- @
-- 'ifoldVL' '.' 'itraverseOf_' ≡ 'id'
-- 'itraverseOf_' '.' 'ifoldVL' ≡ 'id'
-- @
ifoldVL
  :: (forall f. Applicative f => (i -> a -> f u) -> s -> f v)
  -> IxFold i s a
ifoldVL :: forall i a u s v.
(forall (f :: * -> *).
 Applicative f =>
 (i -> a -> f u) -> s -> f v)
-> IxFold i s a
ifoldVL forall (f :: * -> *). Applicative f => (i -> a -> f u) -> s -> f v
f = 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 (p :: * -> * -> * -> *) i a u s v j t b.
(Bicontravariant p, Traversing p) =>
(forall (f :: * -> *).
 Applicative f =>
 (i -> a -> f u) -> s -> f v)
-> Optic__ p j (i -> j) s t a b
ifoldVL__ forall (f :: * -> *). Applicative f => (i -> a -> f u) -> s -> f v
f)
{-# INLINE ifoldVL #-}

-- | Fold with index via embedding into a monoid.
ifoldMapOf
  :: (Is k A_Fold, Monoid m, is `HasSingleIndex` i)
  => Optic' k is s a
  -> (i -> a -> m) -> s -> m
ifoldMapOf :: forall k m (is :: IxList) i s a.
(Is k A_Fold, Monoid m, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> m) -> s -> m
ifoldMapOf Optic' k is s a
o = \i -> a -> m
f -> forall r i a b. IxForget r i a b -> i -> a -> r
runIxForget (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) (forall r i a b. (i -> a -> r) -> IxForget r i a b
IxForget i -> a -> m
f)) forall a. a -> a
id
{-# INLINE ifoldMapOf #-}

-- | Fold with index right-associatively.
ifoldrOf
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a
  -> (i -> a -> r -> r) -> r -> s -> r
ifoldrOf :: forall k (is :: IxList) i s a r.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> r -> r) -> r -> s -> r
ifoldrOf Optic' k is s a
o = \i -> a -> r -> r
iarr r
r0 s
s -> (\Endo r
e -> forall a. Endo a -> a -> a
appEndo Endo r
e r
r0) forall a b. (a -> b) -> a -> b
$ forall k m (is :: IxList) i s a.
(Is k A_Fold, Monoid m, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> m) -> s -> m
ifoldMapOf Optic' k is s a
o (\i
i -> forall a. (a -> a) -> Endo a
Endo forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
#. i -> a -> r -> r
iarr i
i) s
s
{-# INLINE ifoldrOf #-}

-- | Fold with index left-associatively, and strictly.
ifoldlOf'
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a
  -> (i -> r -> a -> r) -> r -> s -> r
ifoldlOf' :: forall k (is :: IxList) i s a r.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> r -> a -> r) -> r -> s -> r
ifoldlOf' Optic' k is s a
o = \i -> r -> a -> r
irar r
r0 s
s -> forall k (is :: IxList) i s a r.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> r -> r) -> r -> s -> r
ifoldrOf Optic' k is s a
o (\i
i a
a r -> r
rr r
r -> r -> r
rr forall a b. (a -> b) -> a -> b
$! i -> r -> a -> r
irar i
i r
r a
a) forall a. a -> a
id s
s r
r0
{-# INLINE ifoldlOf' #-}

-- | Fold with index to a list.
--
-- >>> itoListOf (folded % ifolded) ["abc", "def"]
-- [(0,'a'),(1,'b'),(2,'c'),(0,'d'),(1,'e'),(2,'f')]
--
-- /Note:/ currently indexed optics can be used as non-indexed.
--
-- >>> toListOf (folded % ifolded) ["abc", "def"]
-- "abcdef"
--
itoListOf
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a
  -> s -> [(i, a)]
itoListOf :: forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> s -> [(i, a)]
itoListOf Optic' k is s a
o = forall k (is :: IxList) i s a r.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> r -> r) -> r -> s -> r
ifoldrOf Optic' k is s a
o (\i
i -> (:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (i
i, )) []
{-# INLINE itoListOf #-}

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

-- | Traverse over all of the targets of an 'IxFold', computing an
-- 'Applicative'-based answer, but unlike 'Optics.IxTraversal.itraverseOf' do
-- not construct a new structure.
--
-- >>> itraverseOf_ each (curry print) ("hello","world")
-- (0,"hello")
-- (1,"world")
--
itraverseOf_
  :: (Is k A_Fold, Applicative f, is `HasSingleIndex` i)
  => Optic' k is s a
  -> (i -> a -> f r) -> s -> f ()
#if __GLASGOW_HASKELL__ == 802
-- GHC 8.2.2 needs this to optimize away profunctors when f is not supplied.
itraverseOf_ o = \f ->
#else
itraverseOf_ :: forall k (f :: * -> *) (is :: IxList) i s a r.
(Is k A_Fold, Applicative f, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> f r) -> s -> f ()
itraverseOf_ Optic' k is s a
o i -> a -> f r
f =
#endif
  forall (f :: * -> *) a. Functor f => Traversed f a -> f ()
runTraversed forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k m (is :: IxList) i s a.
(Is k A_Fold, Monoid m, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> m) -> s -> m
ifoldMapOf Optic' k is s a
o (\i
i -> forall (f :: * -> *) a. f a -> Traversed f a
Traversed forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
#. i -> a -> f r
f i
i)
{-# INLINE itraverseOf_ #-}

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

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

-- | Indexed fold via 'FoldableWithIndex' class.
ifolded :: FoldableWithIndex i f => IxFold i (f a) a
ifolded :: forall i (f :: * -> *) a. FoldableWithIndex i f => IxFold i (f a) a
ifolded = 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 (p :: * -> * -> * -> *) i (f :: * -> *) j a t b.
(Bicontravariant p, Traversing p, FoldableWithIndex i f) =>
Optic__ p j (i -> j) (f a) t a b
ifolded__
{-# INLINE ifolded #-}

-- | Obtain an 'IxFold' by lifting an operation that returns a
-- 'FoldableWithIndex' result.
--
-- This can be useful to lift operations from @Data.List@ and elsewhere into an
-- 'IxFold'.
--
-- >>> itoListOf (ifolding words) "how are you"
-- [(0,"how"),(1,"are"),(2,"you")]
ifolding :: FoldableWithIndex i f => (s -> f a) -> IxFold i s a
ifolding :: forall i (f :: * -> *) s a.
FoldableWithIndex i f =>
(s -> f a) -> IxFold i s a
ifolding s -> f a
f = 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 a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> * -> *) b a i c.
Bicontravariant p =>
(b -> a) -> p i a c -> p i b c
contrafirst s -> f a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> * -> *) i (f :: * -> *) j a t b.
(Bicontravariant p, Traversing p, FoldableWithIndex i f) =>
Optic__ p j (i -> j) (f a) t a b
ifolded__
{-# INLINE ifolding #-}

-- | Obtain an 'IxFold' by lifting 'ifoldr' like function.
--
-- >>> itoListOf (ifoldring ifoldr) "hello"
-- [(0,'h'),(1,'e'),(2,'l'),(3,'l'),(4,'o')]
ifoldring
  :: (forall f. Applicative f => (i -> a -> f u -> f u) -> f v -> s -> f w)
  -> IxFold i s a
ifoldring :: forall i a u v s w.
(forall (f :: * -> *).
 Applicative f =>
 (i -> a -> f u -> f u) -> f v -> s -> f w)
-> IxFold i s a
ifoldring forall (f :: * -> *).
Applicative f =>
(i -> a -> f u -> f u) -> f v -> s -> f w
fr = 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 (p :: * -> * -> * -> *) i a u v s w j t b.
(Bicontravariant p, Traversing p) =>
(forall (f :: * -> *).
 Applicative f =>
 (i -> a -> f u -> f u) -> f v -> s -> f w)
-> Optic__ p j (i -> j) s t a b
ifoldring__ forall (f :: * -> *).
Applicative f =>
(i -> a -> f u -> f u) -> f v -> s -> f w
fr)
{-# INLINE ifoldring #-}

-- | Convert an indexed fold to an 'IxAffineFold' that visits the first element
-- of the original fold.
--
-- For the traversal version see 'Optics.IxTraversal.isingular'.
ipre
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a
  -> IxAffineFold i s a
ipre :: forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> IxAffineFold i s a
ipre = forall s i a. (s -> Maybe (i, a)) -> IxAffineFold i s a
iafolding forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> s -> Maybe (i, a)
iheadOf
{-# INLINE ipre #-}

-- | Filter results of an 'IxFold' that don't satisfy a predicate.
--
-- >>> toListOf (ifolded %& ifiltered (>)) [3,2,1,0]
-- [1,0]
--
ifiltered
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => (i -> a -> Bool)
  -> Optic' k is s a
  -> IxFold i s a
ifiltered :: forall k (is :: IxList) i a s.
(Is k A_Fold, HasSingleIndex is i) =>
(i -> a -> Bool) -> Optic' k is s a -> IxFold i s a
ifiltered i -> a -> Bool
p Optic' k is s a
o = forall i a u s v.
(forall (f :: * -> *).
 Applicative f =>
 (i -> a -> f u) -> s -> f v)
-> IxFold i s a
ifoldVL forall a b. (a -> b) -> a -> b
$ \i -> a -> f ()
f ->
  forall k (f :: * -> *) (is :: IxList) i s a r.
(Is k A_Fold, Applicative f, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> f r) -> s -> f ()
itraverseOf_ Optic' k is s a
o (\i
i a
a -> if i -> a -> Bool
p i
i a
a then i -> a -> f ()
f i
i a
a else forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
{-# INLINE ifiltered #-}
-- Note: technically this should be defined per optic kind:
--
-- ifiltered :: _ -> IxFold i s a       -> IxFold i s a
-- ifiltered :: _ -> IxGetter i s a     -> IxAffineFold i s a
-- ifiltered :: _ -> IxAffineFold i s a -> IxAffineFold i s a
--
-- and similarly for (non-existent) unsafeIFiltered.

-- | This allows you to traverse the elements of an 'IxFold' in the opposite
-- order.
ibackwards_
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a
  -> IxFold i s a
ibackwards_ :: forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> IxFold i s a
ibackwards_ Optic' k is s a
o = forall (is :: IxList) i k s t a b.
HasSingleIndex is i =>
Optic k '[] s t a b -> Optic k is s t a b -> Optic k is s t a b
conjoined (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 a b. (a -> b) -> a -> b
$ forall i a u s v.
(forall (f :: * -> *).
 Applicative f =>
 (i -> a -> f u) -> s -> f v)
-> IxFold i s a
ifoldVL forall a b. (a -> b) -> a -> b
$ \i -> a -> f Any
f ->
  forall {k} (f :: k -> *) (a :: k). Backwards f a -> f a
forwards forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
#. forall k (f :: * -> *) (is :: IxList) i s a r.
(Is k A_Fold, Applicative f, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> f r) -> s -> f ()
itraverseOf_ Optic' k is s a
o (\i
i -> forall {k} (f :: k -> *) (a :: k). f a -> Backwards f a
Backwards forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
#. i -> a -> f Any
f i
i)
{-# INLINE ibackwards_ #-}

-- | Return entries of the first 'IxFold', then the second one.
--
-- >>> itoListOf (ifolded `isumming` ibackwards_ ifolded) ["a","b"]
-- [(0,"a"),(1,"b"),(1,"b"),(0,"a")]
--
-- For the traversal version see 'Optics.IxTraversal.iadjoin'.
isumming
  :: (Is k A_Fold, Is l A_Fold,
      is1 `HasSingleIndex` i, is2 `HasSingleIndex` i)
  => Optic' k is1 s a
  -> Optic' l is2 s a
  -> IxFold i s a
isumming :: forall k l (is1 :: IxList) i (is2 :: IxList) s a.
(Is k A_Fold, Is l A_Fold, HasSingleIndex is1 i,
 HasSingleIndex is2 i) =>
Optic' k is1 s a -> Optic' l is2 s a -> IxFold i s a
isumming Optic' k is1 s a
a Optic' l is2 s a
b = forall (is :: IxList) i k s t a b.
HasSingleIndex is i =>
Optic k '[] s t a b -> Optic k is s t a b -> Optic k is s t a b
conjoined (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 is1 s a
a Optic' l is2 s a
b) forall a b. (a -> b) -> a -> b
$ forall i a u s v.
(forall (f :: * -> *).
 Applicative f =>
 (i -> a -> f u) -> s -> f v)
-> IxFold i s a
ifoldVL forall a b. (a -> b) -> a -> b
$ \i -> a -> f Any
f s
s ->
  forall k (f :: * -> *) (is :: IxList) i s a r.
(Is k A_Fold, Applicative f, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> f r) -> s -> f ()
itraverseOf_ Optic' k is1 s a
a i -> a -> f Any
f s
s forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall k (f :: * -> *) (is :: IxList) i s a r.
(Is k A_Fold, Applicative f, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> f r) -> s -> f ()
itraverseOf_ Optic' l is2 s a
b i -> a -> f Any
f s
s
infixr 6 `isumming` -- Same as (<>)
{-# INLINE isumming #-}

-- | Try the first 'IxFold'. If it returns no entries, try the second one.
--
-- >>> itoListOf (_1 % ifolded `ifailing` _2 % ifolded) (["a"], ["b","c"])
-- [(0,"a")]
-- >>> itoListOf (_1 % ifolded `ifailing` _2 % ifolded) ([], ["b","c"])
-- [(0,"b"),(1,"c")]
--
ifailing
  :: (Is k A_Fold, Is l A_Fold, is1 `HasSingleIndex` i, is2 `HasSingleIndex` i)
  => Optic' k is1 s a
  -> Optic' l is2 s a
  -> IxFold i s a
ifailing :: forall k l (is1 :: IxList) i (is2 :: IxList) s a.
(Is k A_Fold, Is l A_Fold, HasSingleIndex is1 i,
 HasSingleIndex is2 i) =>
Optic' k is1 s a -> Optic' l is2 s a -> IxFold i s a
ifailing Optic' k is1 s a
a Optic' l is2 s a
b = forall (is :: IxList) i k s t a b.
HasSingleIndex is i =>
Optic k '[] s t a b -> Optic k is s t a b -> Optic k is s t a b
conjoined (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 is1 s a
a Optic' l is2 s a
b) forall a b. (a -> b) -> a -> b
$ forall i a u s v.
(forall (f :: * -> *).
 Applicative f =>
 (i -> a -> f u) -> s -> f v)
-> IxFold i s a
ifoldVL forall a b. (a -> b) -> a -> b
$ \i -> a -> f Any
f s
s ->
  let OrT Bool
visited f ()
fu = forall k (f :: * -> *) (is :: IxList) i s a r.
(Is k A_Fold, Applicative f, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> f r) -> s -> f ()
itraverseOf_ Optic' k is1 s a
a (\i
i -> forall (f :: * -> *) a. f a -> OrT f a
wrapOrT forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> a -> f Any
f i
i) s
s
  in if Bool
visited
     then f ()
fu
     else forall k (f :: * -> *) (is :: IxList) i s a r.
(Is k A_Fold, Applicative f, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> f r) -> s -> f ()
itraverseOf_ Optic' l is2 s a
b i -> a -> f Any
f s
s
infixl 3 `ifailing` -- Same as (<|>)
{-# INLINE ifailing #-}

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

-- | Retrieve the first entry of an 'IxFold' along with its index.
--
-- >>> iheadOf ifolded [1..10]
-- Just (0,1)
iheadOf
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a -> s -> Maybe (i, a)
iheadOf :: forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> s -> Maybe (i, a)
iheadOf Optic' k is s a
o = forall a. Leftmost a -> Maybe a
getLeftmost forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k m (is :: IxList) i s a.
(Is k A_Fold, Monoid m, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> m) -> s -> m
ifoldMapOf Optic' k is s a
o (\i
i -> forall a. a -> Leftmost a
LLeaf forall b c a. (b -> c) -> (a -> b) -> a -> c
. (i
i, ))
{-# INLINE iheadOf #-}

-- | Retrieve the last entry of an 'IxFold' along with its index.
--
-- >>> ilastOf ifolded [1..10]
-- Just (9,10)
ilastOf
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a -> s -> Maybe (i, a)
ilastOf :: forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> s -> Maybe (i, a)
ilastOf Optic' k is s a
o = forall a. Rightmost a -> Maybe a
getRightmost forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k m (is :: IxList) i s a.
(Is k A_Fold, Monoid m, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> m) -> s -> m
ifoldMapOf Optic' k is s a
o (\i
i -> forall a. a -> Rightmost a
RLeaf forall b c a. (b -> c) -> (a -> b) -> a -> c
. (i
i, ))
{-# INLINE ilastOf #-}

-- | Return whether or not any element viewed through an 'IxFold' satisfies a
-- predicate, with access to the @i@.
--
-- When you don't need access to the index then 'anyOf' is more flexible in what
-- it accepts.
--
-- @
-- 'anyOf' o ≡ 'ianyOf' o '.' 'const'
-- @
ianyOf
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a -> (i -> a -> Bool) -> s -> Bool
ianyOf :: forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> Bool) -> s -> Bool
ianyOf Optic' k is s a
o = \i -> a -> Bool
f -> Any -> Bool
getAny forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
#. forall k m (is :: IxList) i s a.
(Is k A_Fold, Monoid m, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> m) -> s -> m
ifoldMapOf Optic' k is s a
o (\i
i -> Bool -> Any
Any forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
#. i -> a -> Bool
f i
i)
{-# INLINE ianyOf #-}

-- | Return whether or not all elements viewed through an 'IxFold' satisfy a
-- predicate, with access to the @i@.
--
-- When you don't need access to the index then 'allOf' is more flexible in what
-- it accepts.
--
-- @
-- 'allOf' o ≡ 'iallOf' o '.' 'const'
-- @
iallOf
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a -> (i -> a -> Bool) -> s -> Bool
iallOf :: forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> Bool) -> s -> Bool
iallOf Optic' k is s a
o = \i -> a -> Bool
f -> All -> Bool
getAll forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
#. forall k m (is :: IxList) i s a.
(Is k A_Fold, Monoid m, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> m) -> s -> m
ifoldMapOf Optic' k is s a
o (\i
i -> Bool -> All
All forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
#. i -> a -> Bool
f i
i)
{-# INLINE iallOf #-}

-- | Return whether or not none of the elements viewed through an 'IxFold'
-- satisfy a predicate, with access to the @i@.
--
-- When you don't need access to the index then 'noneOf' is more flexible in
-- what it accepts.
--
-- @
-- 'noneOf' o ≡ 'inoneOf' o '.' 'const'
-- @
inoneOf
  :: (Is k A_Fold, is `HasSingleIndex` i)
  => Optic' k is s a -> (i -> a -> Bool) -> s -> Bool
inoneOf :: forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> Bool) -> s -> Bool
inoneOf Optic' k is s a
o = \i -> a -> Bool
f -> Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> Bool) -> s -> Bool
ianyOf Optic' k is s a
o i -> a -> Bool
f
{-# INLINE inoneOf #-}

-- | The 'ifindOf' function takes an 'IxFold', a predicate that is also supplied
-- the index, a structure and returns the left-most element of the structure
-- along with its index matching the predicate, or 'Nothing' if there is no such
-- element.
--
-- When you don't need access to the index then 'findOf' is more flexible in
-- what it accepts.
ifindOf
 :: (Is k A_Fold, is `HasSingleIndex` i)
 => Optic' k is s a -> (i -> a -> Bool) -> s -> Maybe (i, a)
ifindOf :: forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> Bool) -> s -> Maybe (i, a)
ifindOf Optic' k is s a
o = \i -> a -> Bool
p -> forall k (is :: IxList) i s a.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> s -> Maybe (i, a)
iheadOf (forall k (is :: IxList) i a s.
(Is k A_Fold, HasSingleIndex is i) =>
(i -> a -> Bool) -> Optic' k is s a -> IxFold i s a
ifiltered i -> a -> Bool
p Optic' k is s a
o)
{-# INLINE ifindOf #-}

-- | The 'ifindMOf' function takes an 'IxFold', a monadic predicate that is also
-- supplied the index, a structure and returns in the monad the left-most
-- element of the structure matching the predicate, or 'Nothing' if there is no
-- such element.
--
-- When you don't need access to the index then 'findMOf' is more flexible in
-- what it accepts.
ifindMOf
  :: (Is k A_Fold, Monad m, is `HasSingleIndex` i)
  => Optic' k is s a -> (i -> a -> m Bool) -> s -> m (Maybe (i, a))
ifindMOf :: forall k (m :: * -> *) (is :: IxList) i s a.
(Is k A_Fold, Monad m, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> m Bool) -> s -> m (Maybe (i, a))
ifindMOf Optic' k is s a
o = \i -> a -> m Bool
f -> forall k (is :: IxList) i s a r.
(Is k A_Fold, HasSingleIndex is i) =>
Optic' k is s a -> (i -> a -> r -> r) -> r -> s -> r
ifoldrOf Optic' k is s a
o
  (\i
i a
a m (Maybe (i, a))
y -> i -> a -> m Bool
f i
i a
a forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Bool
r -> if Bool
r then forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. a -> Maybe a
Just (i
i, a
a)) else m (Maybe (i, a))
y)
  (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing)
{-# INLINE ifindMOf #-}

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