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

-- 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.

{-# OPTIONS_GHC -Wno-redundant-constraints #-}

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

-- |

-- 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.Semigroup.<>'@ to glue 'Fold's

-- together:

--

-- >>> (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 Prelude ()

import Control.Lens.Internal.Indexed
import Control.Lens.Internal.Prelude
import Control.Lens.Type
import Control.Monad.Reader.Class as Reader
import Control.Monad.State        as State
import Control.Monad.Writer (MonadWriter (..))

-- $setup

-- >>> :set -XNoOverloadedStrings

-- >>> import Control.Lens

-- >>> import Control.Monad.State

-- >>> import Data.List.Lens

-- >>> import Data.Semigroup (Semigroup (..))

-- >>> 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 :: forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to s -> a
k = forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap s -> a
k (forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> 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 :: forall i (p :: * -> * -> *) (f :: * -> *) s a.
(Indexable i p, Contravariant f) =>
(s -> (i, a)) -> Over' p f s a
ito s -> (i, a)
k = forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap s -> (i, a)
k (forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap (forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> (i, a)
k)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 :: forall (p :: * -> * -> *) (f :: * -> *) a s.
(Profunctor p, Contravariant f, Functor f) =>
a -> Optic' p f s a
like a
a = forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to (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 :: forall i (p :: * -> * -> *) (f :: * -> *) a s.
(Indexable i p, Contravariant f, Functor f) =>
i -> a -> Over' p f s a
ilike i
i a
a = forall i (p :: * -> * -> *) (f :: * -> *) s a.
(Indexable i p, Contravariant f) =>
(s -> (i, a)) -> Over' p f s a
ito (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 :: forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting a s a
l = forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Reader.asks (forall {k} a (b :: k). Const a b -> a
getConst 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 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 :: 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 = forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Reader.asks (coerce :: forall a b. Coercible a b => a -> b
coerce LensLike' (Const r) s a
l 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 ^. :: forall s a. s -> Getting a s a -> a
^. Getting a s a
l = forall {k} a (b :: k). Const a b -> a
getConst (Getting a s a
l 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 :: forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting a s a
l = forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
State.gets (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 :: forall s (m :: * -> *) r a.
MonadState s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
uses LensLike' (Const r) s a
l a -> r
f = forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
State.gets (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 :: forall w (m :: * -> *) u a.
MonadWriter w m =>
Getting u w u -> m a -> m (a, u)
listening Getting u w u
l m a
m = do
  (a
a, w
w) <- forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen m a
m
  forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, 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 :: forall w (m :: * -> *) i u a.
MonadWriter w m =>
IndexedGetting i (i, u) w u -> m a -> m (a, (i, u))
ilistening IndexedGetting i (i, u) w u
l m a
m = do
  (a
a, w
w) <- forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen m a
m
  forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, 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 :: forall w (m :: * -> *) v u a.
MonadWriter w m =>
Getting v w u -> (u -> v) -> m a -> m (a, v)
listenings Getting v w u
l u -> v
uv m a
m = do
  (a
a, w
w) <- forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen m a
m
  forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, 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 :: forall w (m :: * -> *) i v u a.
MonadWriter w m =>
IndexedGetting i v w u -> (i -> u -> v) -> m a -> m (a, v)
ilistenings IndexedGetting i v w u
l i -> u -> v
iuv m a
m = do
  (a
a, w
w) <- forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen m a
m
  forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, 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 :: forall s (m :: * -> *) i a.
MonadReader s m =>
IndexedGetting i (i, a) s a -> m (i, a)
iview IndexedGetting i (i, a) s a
l = forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (forall {k} a (b :: k). Const a b -> a
getConst 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 (forall i a b. (i -> a -> b) -> Indexed i a b
Indexed forall a b. (a -> b) -> a -> b
$ \i
i -> forall {k} a (b :: k). a -> Const a b
Const 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 :: forall s (m :: * -> *) i r a.
MonadReader s m =>
IndexedGetting i r s a -> (i -> a -> r) -> m r
iviews IndexedGetting i r s a
l i -> a -> r
f = forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (coerce :: forall a b. Coercible a b => a -> b
coerce IndexedGetting i r s a
l 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 :: forall s (m :: * -> *) i a.
MonadState s m =>
IndexedGetting i (i, a) s a -> m (i, a)
iuse IndexedGetting i (i, a) s a
l = forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (forall {k} a (b :: k). Const a b -> a
getConst 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 (forall i a b. (i -> a -> b) -> Indexed i a b
Indexed forall a b. (a -> b) -> a -> b
$ \i
i -> forall {k} a (b :: k). a -> Const a b
Const 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 :: forall s (m :: * -> *) i r a.
MonadState s m =>
IndexedGetting i r s a -> (i -> a -> r) -> m r
iuses IndexedGetting i r s a
l i -> a -> r
f = forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (coerce :: forall a b. Coercible a b => a -> b
coerce IndexedGetting i r s a
l 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 ^@. :: forall s i a. s -> IndexedGetting i (i, a) s a -> (i, a)
^@. IndexedGetting i (i, a) s a
l = forall {k} a (b :: k). Const a b -> a
getConst forall a b. (a -> b) -> a -> b
$ IndexedGetting i (i, a) s a
l (forall i a b. (i -> a -> b) -> Indexed i a b
Indexed forall a b. (a -> b) -> a -> b
$ \i
i -> forall {k} a (b :: k). a -> Const a b
Const 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 :: forall (p :: * -> * -> *) (q :: * -> * -> *) (f :: * -> *) s t a b.
(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
l p a (f a)
f = forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap forall (f :: * -> *) a b.
(Functor f, Contravariant f) =>
f a -> f b
phantom forall b c a. (b -> c) -> (a -> b) -> a -> c
. Optical p q f s t a b
l forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap forall (f :: * -> *) a b.
(Functor f, Contravariant f) =>
f a -> f b
phantom p a (f a)
f