    {-# LANGUAGE CPP #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE Rank2Types #-}
    {-# LANGUAGE FlexibleContexts #-}

    #ifdef TRUSTWORTHY
    {-# LANGUAGE Trustworthy #-} -- vector, hashable
    #endif

    #include "lens-common.h"

    -------------------------------------------------------------------------------
    -- |
    -- Module      :  Control.Lens.Indexed
    -- Copyright   :  (C) 2012-16 Edward Kmett
    -- License     :  BSD-style (see the file LICENSE)
    -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
    -- Stability   :  provisional
    -- Portability :  Rank2Types
    --
    -- (The classes in here need to be defined together for @DefaultSignatures@ to work.)
    -------------------------------------------------------------------------------
    module Control.Lens.Indexed
      (
      -- * Indexing
        Indexable(..)
      , Conjoined(..)
      , Indexed(..)
      , (<.), (<.>), (.>)
      , selfIndex
      , reindexed
      , icompose
      , indexing
      , indexing64
      -- * Indexed Functors
      , FunctorWithIndex(..)
      -- ** Indexed Functor Combinators
      , imapped
      -- * Indexed Foldables
      , FoldableWithIndex(..)
      -- ** Indexed Foldable Combinators
      , ifolded
      , iany
      , iall
      , inone, none
      , itraverse_
      , ifor_
      , imapM_
      , iforM_
      , iconcatMap
      , ifind
      , ifoldrM
      , ifoldlM
      , itoList
      -- * Converting to Folds
      , withIndex
      , asIndex
      -- * Restricting by Index
      , indices
      , index
      -- * Indexed Traversables
      , TraversableWithIndex(..)
      -- * Indexed Traversable Combinators
      , itraversed
      , ifor
      , imapM
      , iforM
      , imapAccumR
      , imapAccumL
      -- * Indexed Folds with Reified Monoid
      , ifoldMapBy
      , ifoldMapByOf
      -- * Indexed Traversals with Reified Applicative
      , itraverseBy
      , itraverseByOf
      ) where

    import Prelude ()

    import Data.Functor.WithIndex
    import Data.Foldable.WithIndex
    import Data.Traversable.WithIndex

    import Control.Lens.Fold
    import Control.Lens.Getter
    import Control.Lens.Internal.Fold
    import Control.Lens.Internal.Indexed
    import Control.Lens.Internal.Prelude
    import Control.Lens.Setter
    import Control.Lens.Traversal
    import Control.Lens.Type
    import Data.Reflection

    import Data.HashMap.Lazy (HashMap)
    import Data.IntMap (IntMap)
    import Data.Map (Map)
    import Data.Sequence (Seq)
    import Data.Vector (Vector)

    import qualified Data.HashMap.Lazy as HashMap
    import qualified Data.IntMap as IntMap
    import qualified Data.Map as Map
    import qualified Data.Sequence as Seq
    import qualified Data.Vector as Vector

    infixr 9 <.>, <., .>

    -- $setup
    -- >>> :set -XNoOverloadedStrings
    -- >>> import Control.Lens
    -- >>> import qualified Data.Map as Map

    -- | Compose an 'Indexed' function with a non-indexed function.
    --
    -- Mnemonically, the @<@ points to the indexing we want to preserve.
    --
    -- >>> let nestedMap = (fmap Map.fromList . Map.fromList) [(1, [(10, "one,ten"), (20, "one,twenty")]), (2, [(30, "two,thirty"), (40,"two,forty")])]
    -- >>> nestedMap^..(itraversed<.itraversed).withIndex
    -- [(1,"one,ten"),(1,"one,twenty"),(2,"two,thirty"),(2,"two,forty")]
    (<.) :: Indexable i p => (Indexed i s t -> r) -> ((a -> b) -> s -> t) -> p a b -> r
    <. :: forall i (p :: * -> * -> *) s t r a b.
    Indexable i p =>
    (Indexed i s t -> r) -> ((a -> b) -> s -> t) -> p a b -> r
    (<.) Indexed i s t -> r
    f (a -> b) -> s -> t
    g p a b
    h = Indexed i s t -> r
    f (Indexed i s t -> r)
    -> ((i -> s -> t) -> Indexed i s t) -> (i -> s -> t) -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (i -> s -> t) -> Indexed i s t
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed ((i -> s -> t) -> r) -> (i -> s -> t) -> r
    forall a b. (a -> b) -> a -> b
    $ (a -> b) -> s -> t
    g ((a -> b) -> s -> t) -> (i -> a -> b) -> i -> s -> t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . p a b -> i -> a -> b
    forall a b. p a b -> i -> a -> b
    forall i (p :: * -> * -> *) a b.
    Indexable i p =>
    p a b -> i -> a -> b
    indexed p a b
    h
    {-# INLINE (<.) #-}

    -- | Compose a non-indexed function with an 'Indexed' function.
    --
    -- Mnemonically, the @>@ points to the indexing we want to preserve.
    --
    -- This is the same as @('.')@.
    --
    -- @f '.' g@ (and @f '.>' g@) gives you the index of @g@ unless @g@ is index-preserving, like a
    -- 'Prism', 'Iso' or 'Equality', in which case it'll pass through the index of @f@.
    --
    -- >>> let nestedMap = (fmap Map.fromList . Map.fromList) [(1, [(10, "one,ten"), (20, "one,twenty")]), (2, [(30, "two,thirty"), (40,"two,forty")])]
    -- >>> nestedMap^..(itraversed.>itraversed).withIndex
    -- [(10,"one,ten"),(20,"one,twenty"),(30,"two,thirty"),(40,"two,forty")]
    (.>) :: (st -> r) -> (kab -> st) -> kab -> r
    .> :: forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.>) = (st -> r) -> (kab -> st) -> kab -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.)
    {-# INLINE (.>) #-}

    -- | Use a value itself as its own index. This is essentially an indexed version of 'id'.
    --
    -- Note: When used to modify the value, this can break the index requirements assumed by 'indices' and similar,
    -- so this is only properly an 'IndexedGetter', but it can be used as more.
    --
    -- @
    -- 'selfIndex' :: 'IndexedGetter' a a b
    -- @
    selfIndex :: Indexable a p => p a fb -> a -> fb
    selfIndex :: forall a (p :: * -> * -> *) fb. Indexable a p => p a fb -> a -> fb
    selfIndex p a fb
    f a
    a = p a fb -> a -> a -> fb
    forall a b. p a b -> a -> a -> b
    forall i (p :: * -> * -> *) a b.
    Indexable i p =>
    p a b -> i -> a -> b
    indexed p a fb
    f a
    a a
    a
    {-# INLINE selfIndex #-}

    -- | Remap the index.
    reindexed :: Indexable j p => (i -> j) -> (Indexed i a b -> r) -> p a b -> r
    reindexed :: forall j (p :: * -> * -> *) i a b r.
    Indexable j p =>
    (i -> j) -> (Indexed i a b -> r) -> p a b -> r
    reindexed i -> j
    ij Indexed i a b -> r
    f p a b
    g = Indexed i a b -> r
    f (Indexed i a b -> r)
    -> ((i -> a -> b) -> Indexed i a b) -> (i -> a -> b) -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (i -> a -> b) -> Indexed i a b
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed ((i -> a -> b) -> r) -> (i -> a -> b) -> r
    forall a b. (a -> b) -> a -> b
    $ p a b -> j -> a -> b
    forall a b. p a b -> j -> a -> b
    forall i (p :: * -> * -> *) a b.
    Indexable i p =>
    p a b -> i -> a -> b
    indexed p a b
    g (j -> a -> b) -> (i -> j) -> i -> a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . i -> j
    ij
    {-# INLINE reindexed #-}

    -- | Composition of 'Indexed' functions.
    --
    -- Mnemonically, the @\<@ and @\>@ points to the fact that we want to preserve the indices.
    --
    -- >>> let nestedMap = (fmap Map.fromList . Map.fromList) [(1, [(10, "one,ten"), (20, "one,twenty")]), (2, [(30, "two,thirty"), (40,"two,forty")])]
    -- >>> nestedMap^..(itraversed<.>itraversed).withIndex
    -- [((1,10),"one,ten"),((1,20),"one,twenty"),((2,30),"two,thirty"),((2,40),"two,forty")]
    (<.>) :: Indexable (i, j) p => (Indexed i s t -> r) -> (Indexed j a b -> s -> t) -> p a b -> r
    Indexed i s t -> r
    f <.> :: forall i j (p :: * -> * -> *) s t r a b.
    Indexable (i, j) p =>
    (Indexed i s t -> r) -> (Indexed j a b -> s -> t) -> p a b -> r
    <.> Indexed j a b -> s -> t
    g = (i -> j -> (i, j))
    -> (Indexed i s t -> r) -> (Indexed j a b -> s -> t) -> p a b -> r
    forall p (c :: * -> * -> *) i j s t r a b.
    Indexable p c =>
    (i -> j -> p)
    -> (Indexed i s t -> r) -> (Indexed j a b -> s -> t) -> c a b -> r
    icompose (,) Indexed i s t -> r
    f Indexed j a b -> s -> t
    g
    {-# INLINE (<.>) #-}

    -- | Composition of 'Indexed' functions with a user supplied function for combining indices.
    icompose :: Indexable p c => (i -> j -> p) -> (Indexed i s t -> r) -> (Indexed j a b -> s -> t) -> c a b -> r
    icompose :: forall p (c :: * -> * -> *) i j s t r a b.
    Indexable p c =>
    (i -> j -> p)
    -> (Indexed i s t -> r) -> (Indexed j a b -> s -> t) -> c a b -> r
    icompose i -> j -> p
    ijk Indexed i s t -> r
    istr Indexed j a b -> s -> t
    jabst c a b
    cab = Indexed i s t -> r
    istr (Indexed i s t -> r)
    -> ((i -> s -> t) -> Indexed i s t) -> (i -> s -> t) -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (i -> s -> t) -> Indexed i s t
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed ((i -> s -> t) -> r) -> (i -> s -> t) -> r
    forall a b. (a -> b) -> a -> b
    $ \i
    i -> Indexed j a b -> s -> t
    jabst (Indexed j a b -> s -> t)
    -> ((j -> a -> b) -> Indexed j a b) -> (j -> a -> b) -> s -> t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (j -> a -> b) -> Indexed j a b
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed ((j -> a -> b) -> s -> t) -> (j -> a -> b) -> s -> t
    forall a b. (a -> b) -> a -> b
    $ \j
    j -> c a b -> p -> a -> b
    forall a b. c a b -> p -> a -> b
    forall i (p :: * -> * -> *) a b.
    Indexable i p =>
    p a b -> i -> a -> b
    indexed c a b
    cab (p -> a -> b) -> p -> a -> b
    forall a b. (a -> b) -> a -> b
    $ i -> j -> p
    ijk i
    i j
    j
    {-# INLINE icompose #-}

    -------------------------------------------------------------------------------
    -- Restricting by index
    -------------------------------------------------------------------------------

    -- | This allows you to filter an 'IndexedFold', 'IndexedGetter', 'IndexedTraversal' or 'IndexedLens' based on a predicate
    -- on the indices.
    --
    -- >>> ["hello","the","world","!!!"]^..traversed.indices even
    -- ["hello","world"]
    --
    -- >>> over (traversed.indices (>0)) Prelude.reverse $ ["He","was","stressed","o_O"]
    -- ["He","saw","desserts","O_o"]
    indices :: (Indexable i p, Applicative f) => (i -> Bool) -> Optical' p (Indexed i) f a a
    indices :: forall i (p :: * -> * -> *) (f :: * -> *) a.
    (Indexable i p, Applicative f) =>
    (i -> Bool) -> Optical' p (Indexed i) f a a
    indices i -> Bool
    p p a (f a)
    f = (i -> a -> f a) -> Indexed i a (f a)
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed ((i -> a -> f a) -> Indexed i a (f a))
    -> (i -> a -> f a) -> Indexed i a (f a)
    forall a b. (a -> b) -> a -> b
    $ \i
    i a
    a -> if i -> Bool
    p i
    i then p a (f a) -> i -> a -> f a
    forall a b. p a b -> i -> a -> b
    forall i (p :: * -> * -> *) a b.
    Indexable i p =>
    p a b -> i -> a -> b
    indexed p a (f a)
    f i
    i a
    a else a -> f a
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    a
    {-# INLINE indices #-}

    -- | This allows you to filter an 'IndexedFold', 'IndexedGetter', 'IndexedTraversal' or 'IndexedLens' based on an index.
    --
    -- >>> ["hello","the","world","!!!"]^?traversed.index 2
    -- Just "world"
    index :: (Indexable i p, Eq i, Applicative f) => i -> Optical' p (Indexed i) f a a
    index :: forall i (p :: * -> * -> *) (f :: * -> *) a.
    (Indexable i p, Eq i, Applicative f) =>
    i -> Optical' p (Indexed i) f a a
    index i
    j p a (f a)
    f = (i -> a -> f a) -> Indexed i a (f a)
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed ((i -> a -> f a) -> Indexed i a (f a))
    -> (i -> a -> f a) -> Indexed i a (f a)
    forall a b. (a -> b) -> a -> b
    $ \i
    i a
    a -> if i
    j i -> i -> Bool
    forall a. Eq a => a -> a -> Bool
    == i
    i then p a (f a) -> i -> a -> f a
    forall a b. p a b -> i -> a -> b
    forall i (p :: * -> * -> *) a b.
    Indexable i p =>
    p a b -> i -> a -> b
    indexed p a (f a)
    f i
    i a
    a else a -> f a
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    a
    {-# INLINE index #-}

    -------------------------------------------------------------------------------
    -- FunctorWithIndex
    -------------------------------------------------------------------------------

    -- | The 'IndexedSetter' for a 'FunctorWithIndex'.
    --
    -- If you don't need access to the index, then 'mapped' is more flexible in what it accepts.
    imapped :: FunctorWithIndex i f => IndexedSetter i (f a) (f b) a b
    imapped :: forall i (f :: * -> *) a b.
    FunctorWithIndex i f =>
    IndexedSetter i (f a) (f b) a b
    imapped = ((p ~ (->)) => (a -> f b) -> f a -> f (f b))
    -> (p a (f b) -> f a -> f (f b)) -> p a (f b) -> f a -> f (f b)
    forall (p :: * -> * -> *) (q :: * -> * -> *) a b r.
    Conjoined p =>
    ((p ~ (->)) => q (a -> b) r) -> q (p a b) r -> q (p a b) r
    forall (q :: * -> * -> *) a b r.
    ((p ~ (->)) => q (a -> b) r) -> q (p a b) r -> q (p a b) r
    conjoined (p ~ (->)) => (a -> f b) -> f a -> f (f b)
    (a -> f b) -> f a -> f (f b)
    Setter (f a) (f b) a b
    forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
    mapped (((i -> a -> b) -> f a -> f b) -> IndexedSetter i (f a) (f b) a b
    forall i a b s t.
    ((i -> a -> b) -> s -> t) -> IndexedSetter i s t a b
    isets (i -> a -> b) -> f a -> f b
    forall a b. (i -> a -> b) -> f a -> f b
    forall i (f :: * -> *) a b.
    FunctorWithIndex i f =>
    (i -> a -> b) -> f a -> f b
    imap)
    {-# INLINE imapped #-}

    -------------------------------------------------------------------------------
    -- FoldableWithIndex
    -------------------------------------------------------------------------------

    -- | The 'IndexedFold' of a 'FoldableWithIndex' container.
    --
    -- @'ifolded' '.' 'asIndex'@ is a fold over the keys of a 'FoldableWithIndex'.
    --
    -- >>> Data.Map.fromList [(2, "hello"), (1, "world")]^..ifolded.asIndex
    -- [1,2]
    ifolded :: FoldableWithIndex i f => IndexedFold i (f a) a
    ifolded :: forall i (f :: * -> *) a.
    FoldableWithIndex i f =>
    IndexedFold i (f a) a
    ifolded = ((p ~ (->)) => (a -> f a) -> f a -> f (f a))
    -> (p a (f a) -> f a -> f (f a)) -> p a (f a) -> f a -> f (f a)
    forall (p :: * -> * -> *) (q :: * -> * -> *) a b r.
    Conjoined p =>
    ((p ~ (->)) => q (a -> b) r) -> q (p a b) r -> q (p a b) r
    forall (q :: * -> * -> *) a b r.
    ((p ~ (->)) => q (a -> b) r) -> q (p a b) r -> q (p a b) r
    conjoined (p ~ (->)) => (a -> f a) -> f a -> f (f a)
    (a -> f a) -> f a -> f (f a)
    forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
    IndexedFold Int (f a) a
    folded ((p a (f a) -> f a -> f (f a)) -> p a (f a) -> f a -> f (f a))
    -> (p a (f a) -> f a -> f (f a)) -> p a (f a) -> f a -> f (f a)
    forall a b. (a -> b) -> a -> b
    $ \p a (f a)
    f -> f a -> f (f a)
    forall (f :: * -> *) a b.
    (Functor f, Contravariant f) =>
    f a -> f b
    phantom (f a -> f (f a)) -> (f a -> f a) -> f a -> f (f a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Folding f a -> f a
    forall (f :: * -> *) a. Folding f a -> f a
    getFolding (Folding f a -> f a) -> (f a -> Folding f a) -> f a -> f a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (i -> a -> Folding f a) -> f a -> Folding f a
    forall m a. Monoid m => (i -> a -> m) -> f a -> m
    forall i (f :: * -> *) m a.
    (FoldableWithIndex i f, Monoid m) =>
    (i -> a -> m) -> f a -> m
    ifoldMap (\i
    i -> f a -> Folding f a
    forall (f :: * -> *) a. f a -> Folding f a
    Folding (f a -> Folding f a) -> (a -> f a) -> a -> Folding f a
    forall a b c (q :: * -> * -> *).
    Coercible c b =>
    q b c -> (a -> b) -> a -> c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. p a (f a) -> i -> a -> f a
    forall a b. p a b -> i -> a -> b
    forall i (p :: * -> * -> *) a b.
    Indexable i p =>
    p a b -> i -> a -> b
    indexed p a (f a)
    f i
    i)
    {-# INLINE ifolded #-}

    -------------------------------------------------------------------------------
    -- TraversableWithIndex
    -------------------------------------------------------------------------------

    -- | The 'IndexedTraversal' of a 'TraversableWithIndex' container.
    itraversed :: TraversableWithIndex i t => IndexedTraversal i (t a) (t b) a b
    itraversed :: forall i (t :: * -> *) a b.
    TraversableWithIndex i t =>
    IndexedTraversal i (t a) (t b) a b
    itraversed = ((p ~ (->)) => (a -> f b) -> t a -> f (t b))
    -> (p a (f b) -> t a -> f (t b)) -> p a (f b) -> t a -> f (t b)
    forall (p :: * -> * -> *) (q :: * -> * -> *) a b r.
    Conjoined p =>
    ((p ~ (->)) => q (a -> b) r) -> q (p a b) r -> q (p a b) r
    forall (q :: * -> * -> *) a b r.
    ((p ~ (->)) => q (a -> b) r) -> q (p a b) r -> q (p a b) r
    conjoined (p ~ (->)) => (a -> f b) -> t a -> f (t b)
    (a -> f b) -> t a -> f (t b)
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b)
    traverse ((i -> a -> f b) -> t a -> f (t b)
    forall i (t :: * -> *) (f :: * -> *) a b.
    (TraversableWithIndex i t, Applicative f) =>
    (i -> a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (i -> a -> f b) -> t a -> f (t b)
    itraverse ((i -> a -> f b) -> t a -> f (t b))
    -> (p a (f b) -> i -> a -> f b) -> p a (f b) -> t a -> f (t b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . p a (f b) -> i -> a -> f b
    forall a b. p a b -> i -> a -> b
    forall i (p :: * -> * -> *) a b.
    Indexable i p =>
    p a b -> i -> a -> b
    indexed)
    {-# INLINE [0] itraversed #-}

    -------------------------------------------------------------------------------
    -- Instances
    -------------------------------------------------------------------------------

    {-# RULES
    "itraversed -> mapList"    itraversed = sets fmap        :: ASetter [a] [b] a b;
    "itraversed -> imapList"   itraversed = isets imap       :: AnIndexedSetter Int [a] [b] a b;
    "itraversed -> foldrList"  itraversed = foldring foldr   :: Getting (Endo r) [a] a;
    "itraversed -> ifoldrList" itraversed = ifoldring ifoldr :: IndexedGetting Int (Endo r) [a] a;
     #-}

    {-# RULES
    "itraversed -> mapIntMap"    itraversed = sets IntMap.map               :: ASetter (IntMap a) (IntMap b) a b;
    "itraversed -> imapIntMap"   itraversed = isets IntMap.mapWithKey       :: AnIndexedSetter Int (IntMap a) (IntMap b) a b;
    "itraversed -> foldrIntMap"  itraversed = foldring IntMap.foldr         :: Getting (Endo r) (IntMap a) a;
    "itraversed -> ifoldrIntMap" itraversed = ifoldring IntMap.foldrWithKey :: IndexedGetting Int (Endo r) (IntMap a) a;
     #-}

    {-# RULES
    "itraversed -> mapMap"    itraversed = sets Map.map               :: ASetter (Map k a) (Map k b) a b;
    "itraversed -> imapMap"   itraversed = isets Map.mapWithKey       :: AnIndexedSetter k (Map k a) (Map k b) a b;
    "itraversed -> foldrMap"  itraversed = foldring Map.foldr         :: Getting (Endo r) (Map k a) a;
    "itraversed -> ifoldrMap" itraversed = ifoldring Map.foldrWithKey :: IndexedGetting k (Endo r) (Map k a) a;
     #-}

    {-# RULES
    "itraversed -> mapHashMap"    itraversed = sets HashMap.map               :: ASetter (HashMap k a) (HashMap k b) a b;
    "itraversed -> imapHashMap"   itraversed = isets HashMap.mapWithKey       :: AnIndexedSetter k (HashMap k a) (HashMap k b) a b;
    "itraversed -> foldrHashMap"  itraversed = foldring HashMap.foldr         :: Getting (Endo r) (HashMap k a) a;
    "itraversed -> ifoldrHashMap" itraversed = ifoldring HashMap.foldrWithKey :: IndexedGetting k (Endo r) (HashMap k a) a;
     #-}

    {-# RULES
    "itraversed -> mapSeq"    itraversed = sets fmap                    :: ASetter (Seq a) (Seq b) a b;
    "itraversed -> imapSeq"   itraversed = isets Seq.mapWithIndex       :: AnIndexedSetter Int (Seq a) (Seq b) a b;
    "itraversed -> foldrSeq"  itraversed = foldring foldr               :: Getting (Endo r) (Seq a) a;
    "itraversed -> ifoldrSeq" itraversed = ifoldring Seq.foldrWithIndex :: IndexedGetting Int (Endo r) (Seq a) a;
     #-}

    {-# RULES
    "itraversed -> mapVector"    itraversed = sets Vector.map         :: ASetter (Vector a) (Vector b) a b;
    "itraversed -> imapVector"   itraversed = isets Vector.imap       :: AnIndexedSetter Int (Vector a) (Vector b) a b;
    "itraversed -> foldrVector"  itraversed = foldring Vector.foldr   :: Getting (Endo r) (Vector a) a;
    "itraversed -> ifoldrVector" itraversed = ifoldring Vector.ifoldr :: IndexedGetting Int (Endo r) (Vector a) a;
     #-}

    -------------------------------------------------------------------------------
    -- Indexed Folds with Reified Monoid
    -------------------------------------------------------------------------------

    ifoldMapBy :: FoldableWithIndex i t => (r -> r -> r) -> r -> (i -> a -> r) -> t a -> r
    ifoldMapBy :: forall i (t :: * -> *) r a.
    FoldableWithIndex i t =>
    (r -> r -> r) -> r -> (i -> a -> r) -> t a -> r
    ifoldMapBy r -> r -> r
    f r
    z i -> a -> r
    g = (r -> r -> r)
    -> r
    -> (forall s.
        Reifies s (ReifiedMonoid r) =>
        t a -> ReflectedMonoid r s)
    -> t a
    -> r
    forall a t.
    (a -> a -> a)
    -> a
    -> (forall s.
        Reifies s (ReifiedMonoid a) =>
        t -> ReflectedMonoid a s)
    -> t
    -> a
    reifyMonoid r -> r -> r
    f r
    z ((i -> a -> ReflectedMonoid r s) -> t a -> ReflectedMonoid r s
    forall m a. Monoid m => (i -> a -> m) -> t a -> m
    forall i (f :: * -> *) m a.
    (FoldableWithIndex i f, Monoid m) =>
    (i -> a -> m) -> f a -> m
    ifoldMap (\i
    i a
    a -> r -> ReflectedMonoid r s
    forall {k} a (s :: k). a -> ReflectedMonoid a s
    ReflectedMonoid (i -> a -> r
    g i
    i a
    a)))

    ifoldMapByOf :: IndexedFold i t a -> (r -> r -> r) -> r -> (i -> a -> r) -> t -> r
    ifoldMapByOf :: forall i t a r.
    IndexedFold i t a -> (r -> r -> r) -> r -> (i -> a -> r) -> t -> r
    ifoldMapByOf IndexedFold i t a
    l r -> r -> r
    f r
    z i -> a -> r
    g = (r -> r -> r)
    -> r
    -> (forall s.
        Reifies s (ReifiedMonoid r) =>
        t -> ReflectedMonoid r s)
    -> t
    -> r
    forall a t.
    (a -> a -> a)
    -> a
    -> (forall s.
        Reifies s (ReifiedMonoid a) =>
        t -> ReflectedMonoid a s)
    -> t
    -> a
    reifyMonoid r -> r -> r
    f r
    z (IndexedGetting i (ReflectedMonoid r s) t a
    -> (i -> a -> ReflectedMonoid r s) -> t -> ReflectedMonoid r s
    forall i m s a. IndexedGetting i m s a -> (i -> a -> m) -> s -> m
    ifoldMapOf IndexedGetting i (ReflectedMonoid r s) t a
    IndexedFold i t a
    l (\i
    i a
    a -> r -> ReflectedMonoid r s
    forall {k} a (s :: k). a -> ReflectedMonoid a s
    ReflectedMonoid (i -> a -> r
    g i
    i a
    a)))

    itraverseBy :: TraversableWithIndex i t => (forall x. x -> f x) -> (forall x y. f (x -> y) -> f x -> f y) -> (i -> a -> f b) -> t a -> f (t b)
    itraverseBy :: forall i (t :: * -> *) (f :: * -> *) a b.
    TraversableWithIndex i t =>
    (forall x. x -> f x)
    -> (forall x y. f (x -> y) -> f x -> f y)
    -> (i -> a -> f b)
    -> t a
    -> f (t b)
    itraverseBy forall x. x -> f x
    pur forall x y. f (x -> y) -> f x -> f y
    app i -> a -> f b
    f = (forall x. x -> f x)
    -> (forall x y. f (x -> y) -> f x -> f y)
    -> (forall s.
        Reifies s (ReifiedApplicative f) =>
        t a -> ReflectedApplicative f s (t b))
    -> t a
    -> f (t b)
    forall (f :: * -> *) t a.
    (forall x. x -> f x)
    -> (forall x y. f (x -> y) -> f x -> f y)
    -> (forall s.
        Reifies s (ReifiedApplicative f) =>
        t -> ReflectedApplicative f s a)
    -> t
    -> f a
    reifyApplicative x -> f x
    forall x. x -> f x
    pur f (x -> y) -> f x -> f y
    forall x y. f (x -> y) -> f x -> f y
    app ((i -> a -> ReflectedApplicative f s b)
    -> t a -> ReflectedApplicative f s (t b)
    forall i (t :: * -> *) (f :: * -> *) a b.
    (TraversableWithIndex i t, Applicative f) =>
    (i -> a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (i -> a -> f b) -> t a -> f (t b)
    itraverse (\i
    i a
    a -> f b -> ReflectedApplicative f s b
    forall {k} {k1} (f :: k -> *) (s :: k1) (a :: k).
    f a -> ReflectedApplicative f s a
    ReflectedApplicative (i -> a -> f b
    f i
    i a
    a)))

    itraverseByOf :: IndexedTraversal i s t a b -> (forall x. x -> f x) -> (forall x y. f (x -> y) -> f x -> f y) -> (i -> a -> f b) -> s -> f t
    itraverseByOf :: forall i s t a b (f :: * -> *).
    IndexedTraversal i s t a b
    -> (forall x. x -> f x)
    -> (forall x y. f (x -> y) -> f x -> f y)
    -> (i -> a -> f b)
    -> s
    -> f t
    itraverseByOf IndexedTraversal i s t a b
    l forall x. x -> f x
    pur forall x y. f (x -> y) -> f x -> f y
    app i -> a -> f b
    f = (forall x. x -> f x)
    -> (forall x y. f (x -> y) -> f x -> f y)
    -> (forall s.
        Reifies s (ReifiedApplicative f) =>
        s -> ReflectedApplicative f s t)
    -> s
    -> f t
    forall (f :: * -> *) t a.
    (forall x. x -> f x)
    -> (forall x y. f (x -> y) -> f x -> f y)
    -> (forall s.
        Reifies s (ReifiedApplicative f) =>
        t -> ReflectedApplicative f s a)
    -> t
    -> f a
    reifyApplicative x -> f x
    forall x. x -> f x
    pur f (x -> y) -> f x -> f y
    forall x y. f (x -> y) -> f x -> f y
    app ((Indexed i a (ReflectedApplicative f s b)
     -> s -> ReflectedApplicative f s t)
    -> (i -> a -> ReflectedApplicative f s b)
    -> s
    -> ReflectedApplicative f s t
    forall i a (f :: * -> *) b s t.
    (Indexed i a (f b) -> s -> f t) -> (i -> a -> f b) -> s -> f t
    itraverseOf Indexed i a (ReflectedApplicative f s b)
    -> s -> ReflectedApplicative f s t
    IndexedTraversal i s t a b
    l (\i
    i a
    a -> f b -> ReflectedApplicative f s b
    forall {k} {k1} (f :: k -> *) (s :: k1) (a :: k).
    f a -> ReflectedApplicative f s a
    ReflectedApplicative (i -> a -> f b
    f i
    i a
    a)))