    {-# LANGUAGE CPP #-}
    {-# LANGUAGE Rank2Types #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE Trustworthy #-}

    #if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ >= 704
    {-# LANGUAGE NoPolyKinds #-}
    {-# LANGUAGE NoDataKinds #-}
    #endif

    -- Disable the warnings generated by 'to', 'ito', 'like', 'ilike'.
    -- These functions are intended to produce 'Getters'. Without this constraint
    -- users would get warnings when annotating types at uses of these functions.
    #if __GLASGOW_HASKELL__ >= 711
    {-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
    #endif

    #if __GLASGOW_HASKELL__ >= 800
    {-# OPTIONS_GHC -Wno-trustworthy-safe #-}
    #endif
    -------------------------------------------------------------------------------
    -- |
    -- Module      :  Control.Lens.Getter
    -- Copyright   :  (C) 2012-16 Edward Kmett
    -- License     :  BSD-style (see the file LICENSE)
    -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
    -- Stability   :  provisional
    -- Portability :  Rank2Types
    --
    --
    -- A @'Getter' s a@ is just any function @(s -> a)@, which we've flipped
    -- into continuation passing style, @(a -> r) -> s -> r@ and decorated
    -- with 'Const' to obtain:
    --
    -- @type 'Getting' r s a = (a -> 'Const' r a) -> s -> 'Const' r s@
    --
    -- If we restrict access to knowledge about the type 'r', we could get:
    --
    -- @type 'Getter' s a = forall r. 'Getting' r s a@
    --
    -- However, for 'Getter' (but not for 'Getting') we actually permit any
    -- functor @f@ which is an instance of both 'Functor' and 'Contravariant':
    --
    -- @type 'Getter' s a = forall f. ('Contravariant' f, 'Functor' f) => (a -> f a) -> s -> f s@
    --
    -- Everything you can do with a function, you can do with a 'Getter', but
    -- note that because of the continuation passing style ('.') composes them
    -- in the opposite order.
    --
    -- Since it is only a function, every 'Getter' obviously only retrieves a
    -- single value for a given input.
    --
    -- A common question is whether you can combine multiple 'Getter's to
    -- retrieve multiple values. Recall that all 'Getter's are 'Fold's and that
    -- we have a @'Monoid' m => 'Applicative' ('Const' m)@ instance to play
    -- with. Knowing this, we can use @'Data.Monoid.<>'@ to glue 'Fold's
    -- together:
    --
    -- >>> import Data.Monoid
    -- >>> (1, 2, 3, 4, 5) ^.. (_2 <> _3 <> _5)
    -- [2,3,5]
    --
    -------------------------------------------------------------------------------
    module Control.Lens.Getter
      (
      -- * Getters
        Getter, IndexedGetter
      , Getting, IndexedGetting
      , Accessing
      -- * Building Getters
      , to
      , ito
      , like
      , ilike
      -- * Combinators for Getters and Folds
      , (^.)
      , view, views
      , use, uses
      , listening, listenings
      -- * Indexed Getters
      -- ** Indexed Getter Combinators
      , (^@.)
      , iview, iviews
      , iuse, iuses
      , ilistening, ilistenings
      -- * Implementation Details
      , Contravariant(..)
      , getting
      , Const(..)
      ) where

    import Control.Applicative
    import Control.Lens.Internal.Indexed
    import Control.Lens.Type
    import Control.Monad.Reader.Class as Reader
    import Control.Monad.State        as State
    import Control.Monad.Writer       as Writer
    import Data.Functor.Contravariant
    import Data.Profunctor
    import Data.Profunctor.Unsafe

    -- $setup
    -- >>> :set -XNoOverloadedStrings
    -- >>> import Control.Lens
    -- >>> import Data.List.Lens
    -- >>> import Debug.SimpleReflect.Expr
    -- >>> import Debug.SimpleReflect.Vars as Vars hiding (f,g)
    -- >>> let f :: Expr -> Expr; f = Debug.SimpleReflect.Vars.f
    -- >>> let g :: Expr -> Expr; g = Debug.SimpleReflect.Vars.g

    infixl 8 ^., ^@.

    -------------------------------------------------------------------------------
    -- Getters
    -------------------------------------------------------------------------------

    -- | Build an (index-preserving) 'Getter' from an arbitrary Haskell function.
    --
    -- @
    -- 'to' f '.' 'to' g ≡ 'to' (g '.' f)
    -- @
    --
    -- @
    -- a '^.' 'to' f ≡ f a
    -- @
    --
    -- >>> a ^.to f
    -- f a
    --
    -- >>> ("hello","world")^.to snd
    -- "world"
    --
    -- >>> 5^.to succ
    -- 6
    --
    -- >>> (0, -5)^._2.to abs
    -- 5
    --
    -- @
    -- 'to' :: (s -> a) -> 'IndexPreservingGetter' s a
    -- @
    to :: (Profunctor p, Contravariant f) => (s -> a) -> Optic' p f s a
    to :: (s -> a) -> Optic' p f s a
    to k :: s -> a
    k = (s -> a) -> (f a -> f s) -> Optic' p f s a
    forall (p :: * -> * -> *) a b c d.
    Profunctor p =>
    (a -> b) -> (c -> d) -> p b c -> p a d
    dimap s -> a
    k ((s -> a) -> f a -> f s
    forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
    contramap s -> a
    k)
    {-# INLINE to #-}

    -- |
    -- @
    -- 'ito' :: (s -> (i, a)) -> 'IndexedGetter' i s a
    -- @
    ito :: (Indexable i p, Contravariant f) => (s -> (i, a)) -> Over' p f s a
    ito :: (s -> (i, a)) -> Over' p f s a
    ito k :: s -> (i, a)
    k = (s -> (i, a)) -> (f a -> f s) -> ((i, a) -> f a) -> s -> f s
    forall (p :: * -> * -> *) a b c d.
    Profunctor p =>
    (a -> b) -> (c -> d) -> p b c -> p a d
    dimap s -> (i, a)
    k ((s -> a) -> f a -> f s
    forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
    contramap ((i, a) -> a
    forall a b. (a, b) -> b
    snd ((i, a) -> a) -> (s -> (i, a)) -> s -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . s -> (i, a)
    k)) (((i, a) -> f a) -> s -> f s)
    -> (p a (f a) -> (i, a) -> f a) -> Over' p f s a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (i -> a -> f a) -> (i, a) -> f a
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry ((i -> a -> f a) -> (i, a) -> f a)
    -> (p a (f a) -> i -> a -> f a) -> p a (f a) -> (i, a) -> f a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . p a (f a) -> i -> a -> f a
    forall i (p :: * -> * -> *) a b.
    Indexable i p =>
    p a b -> i -> a -> b
    indexed
    {-# INLINE ito #-}

    -- | Build an constant-valued (index-preserving) 'Getter' from an arbitrary Haskell value.
    --
    -- @
    -- 'like' a '.' 'like' b ≡ 'like' b
    -- a '^.' 'like' b ≡ b
    -- a '^.' 'like' b ≡ a '^.' 'to' ('const' b)
    -- @
    --
    -- This can be useful as a second case 'failing' a 'Fold'
    -- e.g. @foo `failing` 'like' 0@
    --
    -- @
    -- 'like' :: a -> 'IndexPreservingGetter' s a
    -- @
    like :: (Profunctor p, Contravariant f, Functor f) => a -> Optic' p f s a
    like :: a -> Optic' p f s a
    like a :: a
    a = (s -> a) -> Optic' p f s a
    forall (p :: * -> * -> *) (f :: * -> *) s a.
    (Profunctor p, Contravariant f) =>
    (s -> a) -> Optic' p f s a
    to (a -> s -> a
    forall a b. a -> b -> a
    const a
    a)
    {-# INLINE like #-}

    -- |
    -- @
    -- 'ilike' :: i -> a -> 'IndexedGetter' i s a
    -- @
    ilike :: (Indexable i p, Contravariant f, Functor f) => i -> a -> Over' p f s a
    ilike :: i -> a -> Over' p f s a
    ilike i :: i
    i a :: a
    a = (s -> (i, a)) -> Over' p f s a
    forall i (p :: * -> * -> *) (f :: * -> *) s a.
    (Indexable i p, Contravariant f) =>
    (s -> (i, a)) -> Over' p f s a
    ito ((i, a) -> s -> (i, a)
    forall a b. a -> b -> a
    const (i
    i, a
    a))
    {-# INLINE ilike #-}

    -- | When you see this in a type signature it indicates that you can
    -- pass the function a 'Lens', 'Getter',
    -- 'Control.Lens.Traversal.Traversal', 'Control.Lens.Fold.Fold',
    -- 'Control.Lens.Prism.Prism', 'Control.Lens.Iso.Iso', or one of
    -- the indexed variants, and it will just \"do the right thing\".
    --
    -- Most 'Getter' combinators are able to be used with both a 'Getter' or a
    -- 'Control.Lens.Fold.Fold' in limited situations, to do so, they need to be
    -- monomorphic in what we are going to extract with 'Control.Applicative.Const'. To be compatible
    -- with 'Lens', 'Control.Lens.Traversal.Traversal' and
    -- 'Control.Lens.Iso.Iso' we also restricted choices of the irrelevant @t@ and
    -- @b@ parameters.
    --
    -- If a function accepts a @'Getting' r s a@, then when @r@ is a 'Data.Monoid.Monoid', then
    -- you can pass a 'Control.Lens.Fold.Fold' (or
    -- 'Control.Lens.Traversal.Traversal'), otherwise you can only pass this a
    -- 'Getter' or 'Lens'.
    type Getting r s a = (a -> Const r a) -> s -> Const r s

    -- | Used to consume an 'Control.Lens.Fold.IndexedFold'.
    type IndexedGetting i m s a = Indexed i a (Const m a) -> s -> Const m s

    -- | This is a convenient alias used when consuming (indexed) getters and (indexed) folds
    -- in a highly general fashion.
    type Accessing p m s a = p a (Const m a) -> s -> Const m s

    -------------------------------------------------------------------------------
    -- Getting Values
    -------------------------------------------------------------------------------

    -- | View the value pointed to by a 'Getter', 'Control.Lens.Iso.Iso' or
    -- 'Lens' or the result of folding over all the results of a
    -- 'Control.Lens.Fold.Fold' or 'Control.Lens.Traversal.Traversal' that points
    -- at a monoidal value.
    --
    -- @
    -- 'view' '.' 'to' ≡ 'id'
    -- @
    --
    -- >>> view (to f) a
    -- f a
    --
    -- >>> view _2 (1,"hello")
    -- "hello"
    --
    -- >>> view (to succ) 5
    -- 6
    --
    -- >>> view (_2._1) ("hello",("world","!!!"))
    -- "world"
    --
    --
    -- As 'view' is commonly used to access the target of a 'Getter' or obtain a monoidal summary of the targets of a 'Fold',
    -- It may be useful to think of it as having one of these more restricted signatures:
    --
    -- @
    -- 'view' ::             'Getter' s a     -> s -> a
    -- 'view' :: 'Data.Monoid.Monoid' m => 'Control.Lens.Fold.Fold' s m       -> s -> m
    -- 'view' ::             'Control.Lens.Iso.Iso'' s a       -> s -> a
    -- 'view' ::             'Lens'' s a      -> s -> a
    -- 'view' :: 'Data.Monoid.Monoid' m => 'Control.Lens.Traversal.Traversal'' s m -> s -> m
    -- @
    --
    -- In a more general setting, such as when working with a 'Monad' transformer stack you can use:
    --
    -- @
    -- 'view' :: 'MonadReader' s m             => 'Getter' s a     -> m a
    -- 'view' :: ('MonadReader' s m, 'Data.Monoid.Monoid' a) => 'Control.Lens.Fold.Fold' s a       -> m a
    -- 'view' :: 'MonadReader' s m             => 'Control.Lens.Iso.Iso'' s a       -> m a
    -- 'view' :: 'MonadReader' s m             => 'Lens'' s a      -> m a
    -- 'view' :: ('MonadReader' s m, 'Data.Monoid.Monoid' a) => 'Control.Lens.Traversal.Traversal'' s a -> m a
    -- @
    view :: MonadReader s m => Getting a s a -> m a
    view :: Getting a s a -> m a
    view l :: Getting a s a
    l = (s -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    Reader.asks (Const a s -> a
    forall a k (b :: k). Const a b -> a
    getConst (Const a s -> a) -> (s -> Const a s) -> s -> a
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. Getting a s a
    l a -> Const a a
    forall k a (b :: k). a -> Const a b
    Const)
    {-# INLINE view #-}

    -- | View a function of the value pointed to by a 'Getter' or 'Lens' or the result of
    -- folding over the result of mapping the targets of a 'Control.Lens.Fold.Fold' or
    -- 'Control.Lens.Traversal.Traversal'.
    --
    -- @
    -- 'views' l f ≡ 'view' (l '.' 'to' f)
    -- @
    --
    -- >>> views (to f) g a
    -- g (f a)
    --
    -- >>> views _2 length (1,"hello")
    -- 5
    --
    -- As 'views' is commonly used to access the target of a 'Getter' or obtain a monoidal summary of the targets of a 'Fold',
    -- It may be useful to think of it as having one of these more restricted signatures:
    --
    -- @
    -- 'views' ::             'Getter' s a     -> (a -> r) -> s -> r
    -- 'views' :: 'Data.Monoid.Monoid' m => 'Control.Lens.Fold.Fold' s a       -> (a -> m) -> s -> m
    -- 'views' ::             'Control.Lens.Iso.Iso'' s a       -> (a -> r) -> s -> r
    -- 'views' ::             'Lens'' s a      -> (a -> r) -> s -> r
    -- 'views' :: 'Data.Monoid.Monoid' m => 'Control.Lens.Traversal.Traversal'' s a -> (a -> m) -> s -> m
    -- @
    --
    -- In a more general setting, such as when working with a 'Monad' transformer stack you can use:
    --
    -- @
    -- 'views' :: 'MonadReader' s m             => 'Getter' s a     -> (a -> r) -> m r
    -- 'views' :: ('MonadReader' s m, 'Data.Monoid.Monoid' r) => 'Control.Lens.Fold.Fold' s a       -> (a -> r) -> m r
    -- 'views' :: 'MonadReader' s m             => 'Control.Lens.Iso.Iso'' s a       -> (a -> r) -> m r
    -- 'views' :: 'MonadReader' s m             => 'Lens'' s a      -> (a -> r) -> m r
    -- 'views' :: ('MonadReader' s m, 'Data.Monoid.Monoid' r) => 'Control.Lens.Traversal.Traversal'' s a -> (a -> r) -> m r
    -- @
    --
    -- @
    -- 'views' :: 'MonadReader' s m => 'Getting' r s a -> (a -> r) -> m r
    -- @
    views :: MonadReader s m => LensLike' (Const r) s a -> (a -> r) -> m r
    views :: LensLike' (Const r) s a -> (a -> r) -> m r
    views l :: LensLike' (Const r) s a
    l f :: a -> r
    f = (s -> r) -> m r
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    Reader.asks (Const r s -> r
    forall a k (b :: k). Const a b -> a
    getConst (Const r s -> r) -> (s -> Const r s) -> s -> r
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. LensLike' (Const r) s a
    l (r -> Const r a
    forall k a (b :: k). a -> Const a b
    Const (r -> Const r a) -> (a -> r) -> a -> Const r a
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. a -> r
    f))
    {-# INLINE views #-}

    -- | View the value pointed to by a 'Getter' or 'Lens' or the
    -- result of folding over all the results of a 'Control.Lens.Fold.Fold' or
    -- 'Control.Lens.Traversal.Traversal' that points at a monoidal values.
    --
    -- This is the same operation as 'view' with the arguments flipped.
    --
    -- The fixity and semantics are such that subsequent field accesses can be
    -- performed with ('Prelude..').
    --
    -- >>> (a,b)^._2
    -- b
    --
    -- >>> ("hello","world")^._2
    -- "world"
    --
    -- >>> import Data.Complex
    -- >>> ((0, 1 :+ 2), 3)^._1._2.to magnitude
    -- 2.23606797749979
    --
    -- @
    -- ('^.') ::             s -> 'Getter' s a     -> a
    -- ('^.') :: 'Data.Monoid.Monoid' m => s -> 'Control.Lens.Fold.Fold' s m       -> m
    -- ('^.') ::             s -> 'Control.Lens.Iso.Iso'' s a       -> a
    -- ('^.') ::             s -> 'Lens'' s a      -> a
    -- ('^.') :: 'Data.Monoid.Monoid' m => s -> 'Control.Lens.Traversal.Traversal'' s m -> m
    -- @
    (^.) :: s -> Getting a s a -> a
    s :: s
    s ^. :: s -> Getting a s a -> a
    ^. l :: Getting a s a
    l = Const a s -> a
    forall a k (b :: k). Const a b -> a
    getConst (Getting a s a
    l a -> Const a a
    forall k a (b :: k). a -> Const a b
    Const s
    s)
    {-# INLINE (^.) #-}

    -------------------------------------------------------------------------------
    -- MonadState
    -------------------------------------------------------------------------------

    -- | Use the target of a 'Lens', 'Control.Lens.Iso.Iso', or
    -- 'Getter' in the current state, or use a summary of a
    -- 'Control.Lens.Fold.Fold' or 'Control.Lens.Traversal.Traversal' that points
    -- to a monoidal value.
    --
    -- >>> evalState (use _1) (a,b)
    -- a
    --
    -- >>> evalState (use _1) ("hello","world")
    -- "hello"
    --
    -- @
    -- 'use' :: 'MonadState' s m             => 'Getter' s a     -> m a
    -- 'use' :: ('MonadState' s m, 'Data.Monoid.Monoid' r) => 'Control.Lens.Fold.Fold' s r       -> m r
    -- 'use' :: 'MonadState' s m             => 'Control.Lens.Iso.Iso'' s a       -> m a
    -- 'use' :: 'MonadState' s m             => 'Lens'' s a      -> m a
    -- 'use' :: ('MonadState' s m, 'Data.Monoid.Monoid' r) => 'Control.Lens.Traversal.Traversal'' s r -> m r
    -- @
    use :: MonadState s m => Getting a s a -> m a
    use :: Getting a s a -> m a
    use l :: Getting a s a
    l = (s -> a) -> m a
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    State.gets (Getting a s a -> s -> a
    forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
    view Getting a s a
    l)
    {-# INLINE use #-}

    -- | Use the target of a 'Lens', 'Control.Lens.Iso.Iso' or
    -- 'Getter' in the current state, or use a summary of a
    -- 'Control.Lens.Fold.Fold' or 'Control.Lens.Traversal.Traversal' that
    -- points to a monoidal value.
    --
    -- >>> evalState (uses _1 length) ("hello","world")
    -- 5
    --
    -- @
    -- 'uses' :: 'MonadState' s m             => 'Getter' s a     -> (a -> r) -> m r
    -- 'uses' :: ('MonadState' s m, 'Data.Monoid.Monoid' r) => 'Control.Lens.Fold.Fold' s a       -> (a -> r) -> m r
    -- 'uses' :: 'MonadState' s m             => 'Lens'' s a      -> (a -> r) -> m r
    -- 'uses' :: 'MonadState' s m             => 'Control.Lens.Iso.Iso'' s a       -> (a -> r) -> m r
    -- 'uses' :: ('MonadState' s m, 'Data.Monoid.Monoid' r) => 'Control.Lens.Traversal.Traversal'' s a -> (a -> r) -> m r
    -- @
    --
    -- @
    -- 'uses' :: 'MonadState' s m => 'Getting' r s t a b -> (a -> r) -> m r
    -- @
    uses :: MonadState s m => LensLike' (Const r) s a -> (a -> r) -> m r
    uses :: LensLike' (Const r) s a -> (a -> r) -> m r
    uses l :: LensLike' (Const r) s a
    l f :: a -> r
    f = (s -> r) -> m r
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    State.gets (LensLike' (Const r) s a -> (a -> r) -> s -> r
    forall s (m :: * -> *) r a.
    MonadReader s m =>
    LensLike' (Const r) s a -> (a -> r) -> m r
    views LensLike' (Const r) s a
    l a -> r
    f)
    {-# INLINE uses #-}

    -- | This is a generalized form of 'listen' that only extracts the portion of
    -- the log that is focused on by a 'Getter'. If given a 'Fold' or a 'Traversal'
    -- then a monoidal summary of the parts of the log that are visited will be
    -- returned.
    --
    -- @
    -- 'listening' :: 'MonadWriter' w m             => 'Getter' w u     -> m a -> m (a, u)
    -- 'listening' :: 'MonadWriter' w m             => 'Lens'' w u      -> m a -> m (a, u)
    -- 'listening' :: 'MonadWriter' w m             => 'Iso'' w u       -> m a -> m (a, u)
    -- 'listening' :: ('MonadWriter' w m, 'Monoid' u) => 'Fold' w u       -> m a -> m (a, u)
    -- 'listening' :: ('MonadWriter' w m, 'Monoid' u) => 'Traversal'' w u -> m a -> m (a, u)
    -- 'listening' :: ('MonadWriter' w m, 'Monoid' u) => 'Prism'' w u     -> m a -> m (a, u)
    -- @
    listening :: MonadWriter w m => Getting u w u -> m a -> m (a, u)
    listening :: Getting u w u -> m a -> m (a, u)
    listening l :: Getting u w u
    l m :: m a
    m = do
      (a :: a
    a, w :: w
    w) <- m a -> m (a, w)
    forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
    listen m a
    m
      (a, u) -> m (a, u)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    a, Getting u w u -> w -> u
    forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
    view Getting u w u
    l w
    w)
    {-# INLINE listening #-}

    -- | This is a generalized form of 'listen' that only extracts the portion of
    -- the log that is focused on by a 'Getter'. If given a 'Fold' or a 'Traversal'
    -- then a monoidal summary of the parts of the log that are visited will be
    -- returned.
    --
    -- @
    -- 'ilistening' :: 'MonadWriter' w m             => 'IndexedGetter' i w u     -> m a -> m (a, (i, u))
    -- 'ilistening' :: 'MonadWriter' w m             => 'IndexedLens'' i w u      -> m a -> m (a, (i, u))
    -- 'ilistening' :: ('MonadWriter' w m, 'Monoid' u) => 'IndexedFold' i w u       -> m a -> m (a, (i, u))
    -- 'ilistening' :: ('MonadWriter' w m, 'Monoid' u) => 'IndexedTraversal'' i w u -> m a -> m (a, (i, u))
    -- @
    ilistening :: MonadWriter w m => IndexedGetting i (i, u) w u -> m a -> m (a, (i, u))
    ilistening :: IndexedGetting i (i, u) w u -> m a -> m (a, (i, u))
    ilistening l :: IndexedGetting i (i, u) w u
    l m :: m a
    m = do
      (a :: a
    a, w :: w
    w) <- m a -> m (a, w)
    forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
    listen m a
    m
      (a, (i, u)) -> m (a, (i, u))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    a, IndexedGetting i (i, u) w u -> w -> (i, u)
    forall s (m :: * -> *) i a.
    MonadReader s m =>
    IndexedGetting i (i, a) s a -> m (i, a)
    iview IndexedGetting i (i, u) w u
    l w
    w)
    {-# INLINE ilistening #-}

    -- | This is a generalized form of 'listen' that only extracts the portion of
    -- the log that is focused on by a 'Getter'. If given a 'Fold' or a 'Traversal'
    -- then a monoidal summary of the parts of the log that are visited will be
    -- returned.
    --
    -- @
    -- 'listenings' :: 'MonadWriter' w m             => 'Getter' w u     -> (u -> v) -> m a -> m (a, v)
    -- 'listenings' :: 'MonadWriter' w m             => 'Lens'' w u      -> (u -> v) -> m a -> m (a, v)
    -- 'listenings' :: 'MonadWriter' w m             => 'Iso'' w u       -> (u -> v) -> m a -> m (a, v)
    -- 'listenings' :: ('MonadWriter' w m, 'Monoid' v) => 'Fold' w u       -> (u -> v) -> m a -> m (a, v)
    -- 'listenings' :: ('MonadWriter' w m, 'Monoid' v) => 'Traversal'' w u -> (u -> v) -> m a -> m (a, v)
    -- 'listenings' :: ('MonadWriter' w m, 'Monoid' v) => 'Prism'' w u     -> (u -> v) -> m a -> m (a, v)
    -- @
    listenings :: MonadWriter w m => Getting v w u -> (u -> v) -> m a -> m (a, v)
    listenings :: Getting v w u -> (u -> v) -> m a -> m (a, v)
    listenings l :: Getting v w u
    l uv :: u -> v
    uv m :: m a
    m = do
      (a :: a
    a, w :: w
    w) <- m a -> m (a, w)
    forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
    listen m a
    m
      (a, v) -> m (a, v)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    a, Getting v w u -> (u -> v) -> w -> v
    forall s (m :: * -> *) r a.
    MonadReader s m =>
    LensLike' (Const r) s a -> (a -> r) -> m r
    views Getting v w u
    l u -> v
    uv w
    w)
    {-# INLINE listenings #-}

    -- | This is a generalized form of 'listen' that only extracts the portion of
    -- the log that is focused on by a 'Getter'. If given a 'Fold' or a 'Traversal'
    -- then a monoidal summary of the parts of the log that are visited will be
    -- returned.
    --
    -- @
    -- 'ilistenings' :: 'MonadWriter' w m             => 'IndexedGetter' w u     -> (i -> u -> v) -> m a -> m (a, v)
    -- 'ilistenings' :: 'MonadWriter' w m             => 'IndexedLens'' w u      -> (i -> u -> v) -> m a -> m (a, v)
    -- 'ilistenings' :: ('MonadWriter' w m, 'Monoid' v) => 'IndexedFold' w u       -> (i -> u -> v) -> m a -> m (a, v)
    -- 'ilistenings' :: ('MonadWriter' w m, 'Monoid' v) => 'IndexedTraversal'' w u -> (i -> u -> v) -> m a -> m (a, v)
    -- @
    ilistenings :: MonadWriter w m => IndexedGetting i v w u -> (i -> u -> v) -> m a -> m (a, v)
    ilistenings :: IndexedGetting i v w u -> (i -> u -> v) -> m a -> m (a, v)
    ilistenings l :: IndexedGetting i v w u
    l iuv :: i -> u -> v
    iuv m :: m a
    m = do
      (a :: a
    a, w :: w
    w) <- m a -> m (a, w)
    forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
    listen m a
    m
      (a, v) -> m (a, v)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    a, IndexedGetting i v w u -> (i -> u -> v) -> w -> v
    forall s (m :: * -> *) i r a.
    MonadReader s m =>
    IndexedGetting i r s a -> (i -> a -> r) -> m r
    iviews IndexedGetting i v w u
    l i -> u -> v
    iuv w
    w)
    {-# INLINE ilistenings #-}

    ------------------------------------------------------------------------------
    -- Indexed Getters
    ------------------------------------------------------------------------------

    -- | View the index and value of an 'IndexedGetter' into the current environment as a pair.
    --
    -- When applied to an 'IndexedFold' the result will most likely be a nonsensical monoidal summary of
    -- the indices tupled with a monoidal summary of the values and probably not whatever it is you wanted.
    iview :: MonadReader s m => IndexedGetting i (i,a) s a -> m (i,a)
    iview :: IndexedGetting i (i, a) s a -> m (i, a)
    iview l :: IndexedGetting i (i, a) s a
    l = (s -> (i, a)) -> m (i, a)
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks (Const (i, a) s -> (i, a)
    forall a k (b :: k). Const a b -> a
    getConst (Const (i, a) s -> (i, a)) -> (s -> Const (i, a) s) -> s -> (i, a)
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. IndexedGetting i (i, a) s a
    l ((i -> a -> Const (i, a) a) -> Indexed i a (Const (i, a) a)
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed ((i -> a -> Const (i, a) a) -> Indexed i a (Const (i, a) a))
    -> (i -> a -> Const (i, a) a) -> Indexed i a (Const (i, a) a)
    forall a b. (a -> b) -> a -> b
    $ \i :: i
    i -> (i, a) -> Const (i, a) a
    forall k a (b :: k). a -> Const a b
    Const ((i, a) -> Const (i, a) a) -> (a -> (i, a)) -> a -> Const (i, a) a
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. (,) i
    i))
    {-# INLINE iview #-}

    -- | View a function of the index and value of an 'IndexedGetter' into the current environment.
    --
    -- When applied to an 'IndexedFold' the result will be a monoidal summary instead of a single answer.
    --
    -- @
    -- 'iviews' ≡ 'Control.Lens.Fold.ifoldMapOf'
    -- @
    iviews :: MonadReader s m => IndexedGetting i r s a -> (i -> a -> r) -> m r
    iviews :: IndexedGetting i r s a -> (i -> a -> r) -> m r
    iviews l :: IndexedGetting i r s a
    l f :: i -> a -> r
    f = (s -> r) -> m r
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks (Const r s -> r
    forall a k (b :: k). Const a b -> a
    getConst (Const r s -> r) -> (s -> Const r s) -> s -> r
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. IndexedGetting i r s a
    l (r -> Const r a
    forall k a (b :: k). a -> Const a b
    Const (r -> Const r a) -> Indexed i a r -> Indexed i a (Const r a)
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. (i -> a -> r) -> Indexed i a r
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed i -> a -> r
    f))
    {-# INLINE iviews #-}

    -- | Use the index and value of an 'IndexedGetter' into the current state as a pair.
    --
    -- When applied to an 'IndexedFold' the result will most likely be a nonsensical monoidal summary of
    -- the indices tupled with a monoidal summary of the values and probably not whatever it is you wanted.
    iuse :: MonadState s m => IndexedGetting i (i,a) s a -> m (i,a)
    iuse :: IndexedGetting i (i, a) s a -> m (i, a)
    iuse l :: IndexedGetting i (i, a) s a
    l = (s -> (i, a)) -> m (i, a)
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets (Const (i, a) s -> (i, a)
    forall a k (b :: k). Const a b -> a
    getConst (Const (i, a) s -> (i, a)) -> (s -> Const (i, a) s) -> s -> (i, a)
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. IndexedGetting i (i, a) s a
    l ((i -> a -> Const (i, a) a) -> Indexed i a (Const (i, a) a)
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed ((i -> a -> Const (i, a) a) -> Indexed i a (Const (i, a) a))
    -> (i -> a -> Const (i, a) a) -> Indexed i a (Const (i, a) a)
    forall a b. (a -> b) -> a -> b
    $ \i :: i
    i -> (i, a) -> Const (i, a) a
    forall k a (b :: k). a -> Const a b
    Const ((i, a) -> Const (i, a) a) -> (a -> (i, a)) -> a -> Const (i, a) a
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. (,) i
    i))
    {-# INLINE iuse #-}

    -- | Use a function of the index and value of an 'IndexedGetter' into the current state.
    --
    -- When applied to an 'IndexedFold' the result will be a monoidal summary instead of a single answer.
    iuses :: MonadState s m => IndexedGetting i r s a -> (i -> a -> r) -> m r
    iuses :: IndexedGetting i r s a -> (i -> a -> r) -> m r
    iuses l :: IndexedGetting i r s a
    l f :: i -> a -> r
    f = (s -> r) -> m r
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets (Const r s -> r
    forall a k (b :: k). Const a b -> a
    getConst (Const r s -> r) -> (s -> Const r s) -> s -> r
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. IndexedGetting i r s a
    l (r -> Const r a
    forall k a (b :: k). a -> Const a b
    Const (r -> Const r a) -> Indexed i a r -> Indexed i a (Const r a)
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. (i -> a -> r) -> Indexed i a r
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed i -> a -> r
    f))
    {-# INLINE iuses #-}

    -- | View the index and value of an 'IndexedGetter' or 'IndexedLens'.
    --
    -- This is the same operation as 'iview' with the arguments flipped.
    --
    -- The fixity and semantics are such that subsequent field accesses can be
    -- performed with ('Prelude..').
    --
    -- @
    -- ('^@.') :: s -> 'IndexedGetter' i s a -> (i, a)
    -- ('^@.') :: s -> 'IndexedLens'' i s a  -> (i, a)
    -- @
    --
    -- The result probably doesn't have much meaning when applied to an 'IndexedFold'.
    (^@.) :: s -> IndexedGetting i (i, a) s a -> (i, a)
    s :: s
    s ^@. :: s -> IndexedGetting i (i, a) s a -> (i, a)
    ^@. l :: IndexedGetting i (i, a) s a
    l = Const (i, a) s -> (i, a)
    forall a k (b :: k). Const a b -> a
    getConst (Const (i, a) s -> (i, a)) -> Const (i, a) s -> (i, a)
    forall a b. (a -> b) -> a -> b
    $ IndexedGetting i (i, a) s a
    l ((i -> a -> Const (i, a) a) -> Indexed i a (Const (i, a) a)
    forall i a b. (i -> a -> b) -> Indexed i a b
    Indexed ((i -> a -> Const (i, a) a) -> Indexed i a (Const (i, a) a))
    -> (i -> a -> Const (i, a) a) -> Indexed i a (Const (i, a) a)
    forall a b. (a -> b) -> a -> b
    $ \i :: i
    i -> (i, a) -> Const (i, a) a
    forall k a (b :: k). a -> Const a b
    Const ((i, a) -> Const (i, a) a) -> (a -> (i, a)) -> a -> Const (i, a) a
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. (,) i
    i) s
    s
    {-# INLINE (^@.) #-}

    -- | Coerce a 'Getter'-compatible 'Optical' to an 'Optical''. This
    -- is useful when using a 'Traversal' that is not simple as a 'Getter' or a
    -- 'Fold'.
    --
    -- @
    -- 'getting' :: 'Traversal' s t a b          -> 'Fold' s a
    -- 'getting' :: 'Lens' s t a b               -> 'Getter' s a
    -- 'getting' :: 'IndexedTraversal' i s t a b -> 'IndexedFold' i s a
    -- 'getting' :: 'IndexedLens' i s t a b      -> 'IndexedGetter' i s a
    -- @
    getting :: (Profunctor p, Profunctor q, Functor f, Contravariant f)
            => Optical p q f s t a b -> Optical' p q f s a
    getting :: Optical p q f s t a b -> Optical' p q f s a
    getting l :: Optical p q f s t a b
    l f :: p a (f a)
    f = (f t -> f s) -> q s (f t) -> q s (f s)
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap f t -> f s
    forall (f :: * -> *) a b.
    (Functor f, Contravariant f) =>
    f a -> f b
    phantom (q s (f t) -> q s (f s))
    -> Optical p q f s t a b -> p a (f b) -> q s (f s)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optical p q f s t a b
    l (p a (f b) -> q s (f s)) -> p a (f b) -> q s (f s)
    forall a b. (a -> b) -> a -> b
    $ (f a -> f b) -> p a (f a) -> p a (f b)
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap f a -> f b
    forall (f :: * -> *) a b.
    (Functor f, Contravariant f) =>
    f a -> f b
    phantom p a (f a)
    f