{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes            #-}

-- | An indexed version of @Plated@.
--
-- This module provides a similar API to lens' @Plated@, with the following key
-- differences:
--
--   * all corresponding functions from @Plated@ have a @i@ prefix, similarly to
--     what lens does (see @over@ and @iover@ for instance);
--   * all @Getter@, @Setter@ and @LensLike@ are replaced by their @Indexed@
--     equivalents, and all take an additional index parameter
module Control.Lens.IndexedPlated
  ( -- * Indexed plated
    IndexedPlated (..)
    -- * Children
  , ichildren
    -- * Rewrite
  , irewrite
  , irewriteOf
  , irewriteOn
  , irewriteOnOf
  , irewriteM
  , irewriteMOf
  , irewriteMOn
  , irewriteMOnOf
    -- * Universe
  , iuniverse
  , iuniverseOf
  , iuniverseOn
  , iuniverseOnOf
    -- * Cosmos
  , icosmos
  , icosmosOf
  , icosmosOn
  , icosmosOnOf
    -- * Transform
  , itransform
  , itransformOf
  , itransformOn
  , itransformOnOf
  , itransformM
  , itransformMOf
  , itransformMOn
  , itransformMOnOf
    -- * Paramorphisms
  , ipara
  , iparaOf
  ) where

import Control.Applicative
import Control.Lens
import Data.Monoid


--------------------------------------------------------------------------------
-- Indexed plated

class IndexedPlated i a where
  -- | 'IndexedTraversal' of the immediate children of this structure.
  iplate :: i -> IndexedTraversal' i a a


--------------------------------------------------------------------------------
-- Children

-- | Given an 'IndexedPlated' container and its index, extract the immediate
-- descendants of the container and their indices.
--
-- @since 0.1.0
ichildren :: IndexedPlated i a => i -> a -> [(i, a)]
ichildren :: forall i a. IndexedPlated i a => i -> a -> [(i, a)]
ichildren i
p = forall i a s. IndexedGetting i (Endo [(i, a)]) s a -> s -> [(i, a)]
itoListOf (forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate i
p)
{-# INLINE ichildren #-}


--------------------------------------------------------------------------------
-- Rewrite

-- | Rewrite a container by applying a rule everywhere possible. If the rule
-- returns @Nothing@, the value remains unchanged, but while it returns a new
-- value the transformation will be recursively applied. This guarantees that
-- this function is applied everywhere possible, and that the result does not
-- contain any eligible value.
--
-- @since 0.1.0
irewrite :: IndexedPlated i a => (i -> a -> Maybe a) -> i -> a -> a
irewrite :: forall i a. IndexedPlated i a => (i -> a -> Maybe a) -> i -> a -> a
irewrite = forall i a b.
(i -> IndexedSetter i a b a b)
-> (i -> b -> Maybe a) -> i -> a -> b
irewriteOf forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate
{-# INLINE irewrite #-}

-- | Rewrite a container by applying a rule everywhere possible, using the
-- provided lens to locate immediate children. If the rule returns @Nothing@,
-- the value remains unchanged, but while it returns a new value the
-- transformation will be recursively applied. This guarantees that this
-- function is applied everywhere possible, and that the result does not contain
-- any eligible value.
--
-- @since 0.1.0
irewriteOf :: (i -> IndexedSetter i a b a b) -> (i -> b -> Maybe a) -> i -> a -> b
irewriteOf :: forall i a b.
(i -> IndexedSetter i a b a b)
-> (i -> b -> Maybe a) -> i -> a -> b
irewriteOf i -> IndexedSetter i a b a b
l i -> b -> Maybe a
f = i -> a -> b
go
  where
    go :: i -> a -> b
go = forall i a b.
(i -> IndexedSetter i a b a b) -> (i -> b -> b) -> i -> a -> b
itransformOf i -> IndexedSetter i a b a b
l (\i
i b
x -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe b
x (i -> a -> b
go i
i) (i -> b -> Maybe a
f i
i b
x))
{-# INLINE irewriteOf #-}

-- | Similar to 'irewrite', but performed recursively over part of a larger
-- structure.
--
-- @since 0.1.0
irewriteOn :: IndexedPlated i a => ASetter s t a a -> (i -> a -> Maybe a) -> i -> s -> t
irewriteOn :: forall i a s t.
IndexedPlated i a =>
ASetter s t a a -> (i -> a -> Maybe a) -> i -> s -> t
irewriteOn ASetter s t a a
b i -> a -> Maybe a
f i
i = forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter s t a a
b forall a b. (a -> b) -> a -> b
$ forall i a. IndexedPlated i a => (i -> a -> Maybe a) -> i -> a -> a
irewrite i -> a -> Maybe a
f i
i
{-# INLINE irewriteOn #-}

-- | Similar to 'irewriteOf', but performed recursively over part of a larger
-- structure.
--
-- @since 0.1.0
irewriteOnOf :: ASetter s t a b -> (i -> IndexedSetter i a b a b) -> (i -> b -> Maybe a) -> i -> s -> t
irewriteOnOf :: forall s t a b i.
ASetter s t a b
-> (i -> IndexedSetter i a b a b)
-> (i -> b -> Maybe a)
-> i
-> s
-> t
irewriteOnOf ASetter s t a b
b i -> IndexedSetter i a b a b
l i -> b -> Maybe a
f i
i = forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter s t a b
b forall a b. (a -> b) -> a -> b
$ forall i a b.
(i -> IndexedSetter i a b a b)
-> (i -> b -> Maybe a) -> i -> a -> b
irewriteOf i -> IndexedSetter i a b a b
l i -> b -> Maybe a
f i
i
{-# INLINE irewriteOnOf #-}

-- | Similar to 'irewrite', but using a monadic rule.
--
-- @since 0.1.0
irewriteM :: (Monad m, IndexedPlated i a) => (i -> a -> m (Maybe a)) -> i -> a -> m a
irewriteM :: forall (m :: * -> *) i a.
(Monad m, IndexedPlated i a) =>
(i -> a -> m (Maybe a)) -> i -> a -> m a
irewriteM = forall (m :: * -> *) i a b.
Monad m =>
(i -> IndexedLensLike i (WrappedMonad m) a b a b)
-> (i -> b -> m (Maybe a)) -> i -> a -> m b
irewriteMOf forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate
{-# INLINE irewriteM #-}

-- | Similar to 'irewriteOf', but using a monadic rule.
--
-- @since 0.1.0
irewriteMOf :: Monad m => (i -> IndexedLensLike i (WrappedMonad m) a b a b) -> (i -> b -> m (Maybe a)) -> i -> a -> m b
irewriteMOf :: forall (m :: * -> *) i a b.
Monad m =>
(i -> IndexedLensLike i (WrappedMonad m) a b a b)
-> (i -> b -> m (Maybe a)) -> i -> a -> m b
irewriteMOf i -> IndexedLensLike i (WrappedMonad m) a b a b
l i -> b -> m (Maybe a)
f = i -> a -> m b
go
  where
    go :: i -> a -> m b
go = forall (m :: * -> *) i a b.
Monad m =>
(i -> IndexedLensLike i (WrappedMonad m) a b a b)
-> (i -> b -> m b) -> i -> a -> m b
itransformMOf i -> IndexedLensLike i (WrappedMonad m) a b a b
l (\i
i b
x -> i -> b -> m (Maybe a)
f i
i b
x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (f :: * -> *) a. Applicative f => a -> f a
pure b
x) (i -> a -> m b
go i
i))
{-# INLINE irewriteMOf #-}

-- | Similar to 'irewriteOn', but using a monadic rule.
--
-- @since 0.1.0
irewriteMOn :: (Monad m, IndexedPlated i a) => LensLike (WrappedMonad m) s t a a -> (i -> a -> m (Maybe a)) -> i -> s -> m t
irewriteMOn :: forall (m :: * -> *) i a s t.
(Monad m, IndexedPlated i a) =>
LensLike (WrappedMonad m) s t a a
-> (i -> a -> m (Maybe a)) -> i -> s -> m t
irewriteMOn LensLike (WrappedMonad m) s t a a
b i -> a -> m (Maybe a)
f i
i = forall (m :: * -> *) s t a b.
LensLike (WrappedMonad m) s t a b -> (a -> m b) -> s -> m t
mapMOf LensLike (WrappedMonad m) s t a a
b forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) i a.
(Monad m, IndexedPlated i a) =>
(i -> a -> m (Maybe a)) -> i -> a -> m a
irewriteM i -> a -> m (Maybe a)
f i
i
{-# INLINE irewriteMOn #-}

-- | Similar to 'irewriteOnOf', but using a monadic rule.
--
-- @since 0.1.0
irewriteMOnOf :: Monad m => LensLike (WrappedMonad m) s t a b -> (i -> IndexedLensLike i (WrappedMonad m) a b a b) -> (i -> b -> m (Maybe a)) -> i -> s -> m t
irewriteMOnOf :: forall (m :: * -> *) s t a b i.
Monad m =>
LensLike (WrappedMonad m) s t a b
-> (i -> IndexedLensLike i (WrappedMonad m) a b a b)
-> (i -> b -> m (Maybe a))
-> i
-> s
-> m t
irewriteMOnOf LensLike (WrappedMonad m) s t a b
b i -> IndexedLensLike i (WrappedMonad m) a b a b
l i -> b -> m (Maybe a)
f i
i = forall (m :: * -> *) s t a b.
LensLike (WrappedMonad m) s t a b -> (a -> m b) -> s -> m t
mapMOf LensLike (WrappedMonad m) s t a b
b forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) i a b.
Monad m =>
(i -> IndexedLensLike i (WrappedMonad m) a b a b)
-> (i -> b -> m (Maybe a)) -> i -> a -> m b
irewriteMOf i -> IndexedLensLike i (WrappedMonad m) a b a b
l i -> b -> m (Maybe a)
f i
i
{-# INLINE irewriteMOnOf #-}


--------------------------------------------------------------------------------
-- Universe

-- | Retrieve all of the transitive descendants (and their indices) of an
-- 'IndexedPlated' container, including itself.
--
-- @since 0.1.0
iuniverse :: forall i a. IndexedPlated i a => i -> a -> [(i, a)]
iuniverse :: forall i a. IndexedPlated i a => i -> a -> [(i, a)]
iuniverse = forall i a.
(i -> IndexedGetting i (Endo [(i, a)]) a a) -> i -> a -> [(i, a)]
iuniverseOf forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate
{-# INLINE iuniverse #-}

-- | Retrieve all of the transitive descendants (and their indices) of a
-- container, including itself, using the provided lens to locate immediate
-- children.
--
-- @since 0.1.0
iuniverseOf :: (i -> IndexedGetting i (Endo [(i, a)]) a a) -> i -> a -> [(i, a)]
iuniverseOf :: forall i a.
(i -> IndexedGetting i (Endo [(i, a)]) a a) -> i -> a -> [(i, a)]
iuniverseOf i -> IndexedGetting i (Endo [(i, a)]) a a
l = \i
i a
x -> forall a. Endo a -> a -> a
appEndo (forall i a.
(i -> IndexedGetting i (Endo [(i, a)]) a a)
-> i -> a -> Endo [(i, a)]
iuniverseOf' i -> IndexedGetting i (Endo [(i, a)]) a a
l i
i a
x) []
{-# INLINE iuniverseOf #-}

iuniverseOf' :: (i -> IndexedGetting i (Endo [(i, a)]) a a) -> i -> a -> Endo [(i, a)]
iuniverseOf' :: forall i a.
(i -> IndexedGetting i (Endo [(i, a)]) a a)
-> i -> a -> Endo [(i, a)]
iuniverseOf' i -> IndexedGetting i (Endo [(i, a)]) a a
l = i -> a -> Endo [(i, a)]
go
  where
    go :: i -> a -> Endo [(i, a)]
go i
i a
a = forall a. (a -> a) -> Endo a
Endo ((i
i, a
a) forall a. a -> [a] -> [a]
:) forall a. Semigroup a => a -> a -> a
<> forall i m s a. IndexedGetting i m s a -> (i -> a -> m) -> s -> m
ifoldMapOf (i -> IndexedGetting i (Endo [(i, a)]) a a
l i
i) i -> a -> Endo [(i, a)]
go a
a
{-# INLINE iuniverseOf' #-}

-- | Similar to 'iuniverse', but performed recursively over part of a larger
-- structure.
--
-- @since 0.1.0
iuniverseOn ::  IndexedPlated i a => Getting (Endo [(i, a)]) s a -> i -> s -> [(i, a)]
iuniverseOn :: forall i a s.
IndexedPlated i a =>
Getting (Endo [(i, a)]) s a -> i -> s -> [(i, a)]
iuniverseOn Getting (Endo [(i, a)]) s a
b = forall i a s.
Getting (Endo [(i, a)]) s a
-> (i -> IndexedGetting i (Endo [(i, a)]) a a)
-> i
-> s
-> [(i, a)]
iuniverseOnOf Getting (Endo [(i, a)]) s a
b forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate
{-# INLINE iuniverseOn #-}

-- | Similar to 'iuniverseOf', but performed recursively over part of a larger
-- structure.
--
-- @since 0.1.0
iuniverseOnOf :: Getting (Endo [(i, a)]) s a -> (i -> IndexedGetting i (Endo [(i, a)]) a a) -> i -> s -> [(i, a)]
iuniverseOnOf :: forall i a s.
Getting (Endo [(i, a)]) s a
-> (i -> IndexedGetting i (Endo [(i, a)]) a a)
-> i
-> s
-> [(i, a)]
iuniverseOnOf Getting (Endo [(i, a)]) s a
b i -> IndexedGetting i (Endo [(i, a)]) a a
p i
i s
x = forall a. Endo a -> a -> a
appEndo (forall r s a. Getting r s a -> (a -> r) -> s -> r
foldMapOf Getting (Endo [(i, a)]) s a
b (forall i a.
(i -> IndexedGetting i (Endo [(i, a)]) a a)
-> i -> a -> Endo [(i, a)]
iuniverseOf' i -> IndexedGetting i (Endo [(i, a)]) a a
p i
i) s
x) []
{-# INLINE iuniverseOnOf #-}


--------------------------------------------------------------------------------
-- Cosmos

-- | Fold over all transitive descendants (and their indices) of an
-- 'IndexedPlated' container, including itself.
--
-- @since 0.1.0
icosmos :: IndexedPlated i a => i -> IndexedFold i a a
icosmos :: forall i a. IndexedPlated i a => i -> IndexedFold i a a
icosmos = forall (f :: * -> *) i a.
(Applicative f, Contravariant f) =>
(i -> IndexedLensLike' i f a a) -> i -> IndexedLensLike' i f a a
icosmosOf forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate
{-# INLINE icosmos #-}

-- | Fold over all transitive descendants (and their indices) of a container,
-- including itself, using the provided lens to locate immediate children.
--
-- @since 0.1.0
icosmosOf :: (Applicative f, Contravariant f) => (i -> IndexedLensLike' i f a a) -> (i -> IndexedLensLike' i f a a)
icosmosOf :: forall (f :: * -> *) i a.
(Applicative f, Contravariant f) =>
(i -> IndexedLensLike' i f a a) -> i -> IndexedLensLike' i f a a
icosmosOf i -> IndexedLensLike' i f a a
d i
i p a (f a)
f a
s = forall i (p :: * -> * -> *) a b.
Indexable i p =>
p a b -> i -> a -> b
indexed p a (f a)
f i
i a
s forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> i -> IndexedLensLike' i f a a
d i
i (forall (f :: * -> *) i a.
(Applicative f, Contravariant f) =>
(i -> IndexedLensLike' i f a a) -> i -> IndexedLensLike' i f a a
icosmosOf i -> IndexedLensLike' i f a a
d i
i p a (f a)
f) a
s
{-# INLINE icosmosOf #-}

-- | Similar to 'icosmos', but performed recursively over part of a larger
-- structure.
--
-- @since 0.1.0
icosmosOn :: (Applicative f, Contravariant f, IndexedPlated i a) => LensLike' f s a -> (i -> LensLike' f s a)
icosmosOn :: forall (f :: * -> *) i a s.
(Applicative f, Contravariant f, IndexedPlated i a) =>
LensLike' f s a -> i -> LensLike' f s a
icosmosOn LensLike' f s a
d = forall (f :: * -> *) s a i.
(Applicative f, Contravariant f) =>
LensLike' f s a
-> (i -> IndexedLensLike' i f a a) -> i -> LensLike' f s a
icosmosOnOf LensLike' f s a
d forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate
{-# INLINE icosmosOn #-}

-- | Similar to 'icosmosOf', but performed recursively over part of a larger
-- structure.
--
-- @since 0.1.0
icosmosOnOf :: (Applicative f, Contravariant f) => LensLike' f s a -> (i -> IndexedLensLike' i f a a) -> (i -> LensLike' f s a)
icosmosOnOf :: forall (f :: * -> *) s a i.
(Applicative f, Contravariant f) =>
LensLike' f s a
-> (i -> IndexedLensLike' i f a a) -> i -> LensLike' f s a
icosmosOnOf LensLike' f s a
d i -> IndexedLensLike' i f a a
p i
i = LensLike' f s a
d forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) i a.
(Applicative f, Contravariant f) =>
(i -> IndexedLensLike' i f a a) -> i -> IndexedLensLike' i f a a
icosmosOf i -> IndexedLensLike' i f a a
p i
i
{-# INLINE icosmosOnOf #-}


--------------------------------------------------------------------------------
-- Transform

-- | Recursively transform every element in the structure, in a bottom-up
-- manner.
--
-- @since 0.1.0
itransform :: IndexedPlated i a => (i -> a -> a) -> i -> a -> a
itransform :: forall i a. IndexedPlated i a => (i -> a -> a) -> i -> a -> a
itransform = forall i a b.
(i -> IndexedSetter i a b a b) -> (i -> b -> b) -> i -> a -> b
itransformOf forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate
{-# INLINE itransform #-}

-- | Recursively transform every element in the structure, in a bottom-up
-- manner, using the provided lens to locate immediate children.
--
-- @since 0.1.0
itransformOf :: (i -> IndexedSetter i a b a b) -> (i -> b -> b) -> i -> a -> b
itransformOf :: forall i a b.
(i -> IndexedSetter i a b a b) -> (i -> b -> b) -> i -> a -> b
itransformOf i -> IndexedSetter i a b a b
l i -> b -> b
f = i -> a -> b
go
  where
    go :: i -> a -> b
go i
i = i -> b -> b
f i
i forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i s t a b.
AnIndexedSetter i s t a b -> (i -> a -> b) -> s -> t
iover (i -> IndexedSetter i a b a b
l i
i) i -> a -> b
go
{-# INLINE itransformOf #-}

-- | Similar to 'itransform', but performed recursively over part of a larger
-- structure.
--
-- @since 0.1.0
itransformOn :: IndexedPlated i a => ASetter s t a a -> (i -> a -> a) -> i -> s -> t
itransformOn :: forall i a s t.
IndexedPlated i a =>
ASetter s t a a -> (i -> a -> a) -> i -> s -> t
itransformOn ASetter s t a a
b i -> a -> a
i = forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter s t a a
b forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i a. IndexedPlated i a => (i -> a -> a) -> i -> a -> a
itransform i -> a -> a
i
{-# INLINE itransformOn #-}

-- | Similar to 'itransformOf', but performed recursively over part of a larger
-- structure.
--
-- @since 0.1.0
itransformOnOf :: ASetter s t a b -> (i -> IndexedSetter i a b a b) -> (i -> b -> b) -> i -> s -> t
itransformOnOf :: forall s t a b i.
ASetter s t a b
-> (i -> IndexedSetter i a b a b) -> (i -> b -> b) -> i -> s -> t
itransformOnOf ASetter s t a b
b i -> IndexedSetter i a b a b
l i -> b -> b
f = forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter s t a b
b forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i a b.
(i -> IndexedSetter i a b a b) -> (i -> b -> b) -> i -> a -> b
itransformOf i -> IndexedSetter i a b a b
l i -> b -> b
f
{-# INLINE itransformOnOf #-}

-- | Similar to 'itransform', but using a monadic rule.
--
-- @since 0.1.0
itransformM :: (Monad m, IndexedPlated i a) => (i -> a -> m a) -> i -> a -> m a
itransformM :: forall (m :: * -> *) i a.
(Monad m, IndexedPlated i a) =>
(i -> a -> m a) -> i -> a -> m a
itransformM = forall (m :: * -> *) i a b.
Monad m =>
(i -> IndexedLensLike i (WrappedMonad m) a b a b)
-> (i -> b -> m b) -> i -> a -> m b
itransformMOf forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate
{-# INLINE itransformM #-}

-- | Similar to 'itransformOn', but using a monadic rule.
--
-- @since 0.1.0
itransformMOn :: (Monad m, IndexedPlated i a) => LensLike (WrappedMonad m) s t a a -> (i -> a -> m a) -> i -> s -> m t
itransformMOn :: forall (m :: * -> *) i a s t.
(Monad m, IndexedPlated i a) =>
LensLike (WrappedMonad m) s t a a
-> (i -> a -> m a) -> i -> s -> m t
itransformMOn LensLike (WrappedMonad m) s t a a
b i -> a -> m a
f = forall (m :: * -> *) s t a b.
LensLike (WrappedMonad m) s t a b -> (a -> m b) -> s -> m t
mapMOf LensLike (WrappedMonad m) s t a a
b forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) i a.
(Monad m, IndexedPlated i a) =>
(i -> a -> m a) -> i -> a -> m a
itransformM i -> a -> m a
f
{-# INLINE itransformMOn #-}

-- | Similar to 'itransformOf', but using a monadic rule.
--
-- @since 0.1.0
itransformMOf :: Monad m => (i -> IndexedLensLike i (WrappedMonad m) a b a b) -> (i -> b -> m b) -> i -> a -> m b
itransformMOf :: forall (m :: * -> *) i a b.
Monad m =>
(i -> IndexedLensLike i (WrappedMonad m) a b a b)
-> (i -> b -> m b) -> i -> a -> m b
itransformMOf i -> IndexedLensLike i (WrappedMonad m) a b a b
l i -> b -> m b
f = i -> a -> m b
go
  where
    go :: i -> a -> m b
go i
i a
t = forall i (m :: * -> *) s t a b.
Over (Indexed i) (WrappedMonad m) s t a b
-> (i -> a -> m b) -> s -> m t
imapMOf (i -> IndexedLensLike i (WrappedMonad m) a b a b
l i
i) i -> a -> m b
go a
t forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= i -> b -> m b
f i
i
{-# INLINE itransformMOf #-}

-- | Similar to 'itransformOnOf', but using a monadic rule.
--
-- @since 0.1.0
itransformMOnOf :: Monad m => LensLike (WrappedMonad m) s t a b -> (i -> IndexedLensLike i (WrappedMonad m) a b a b) -> (i -> b -> m b) -> i -> s -> m t
itransformMOnOf :: forall (m :: * -> *) s t a b i.
Monad m =>
LensLike (WrappedMonad m) s t a b
-> (i -> IndexedLensLike i (WrappedMonad m) a b a b)
-> (i -> b -> m b)
-> i
-> s
-> m t
itransformMOnOf LensLike (WrappedMonad m) s t a b
b i -> IndexedLensLike i (WrappedMonad m) a b a b
l i -> b -> m b
f = forall (m :: * -> *) s t a b.
LensLike (WrappedMonad m) s t a b -> (a -> m b) -> s -> m t
mapMOf LensLike (WrappedMonad m) s t a b
b forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) i a b.
Monad m =>
(i -> IndexedLensLike i (WrappedMonad m) a b a b)
-> (i -> b -> m b) -> i -> a -> m b
itransformMOf i -> IndexedLensLike i (WrappedMonad m) a b a b
l i -> b -> m b
f
{-# INLINE itransformMOnOf #-}


--------------------------------------------------------------------------------
-- Paramorphisms

-- | Perform a fold-like computation on each value within a container.
--
-- @since 0.1.0
ipara :: IndexedPlated i a => (i -> a -> [r] -> r) -> i -> a -> r
ipara :: forall i a r.
IndexedPlated i a =>
(i -> a -> [r] -> r) -> i -> a -> r
ipara = forall i a r.
(i -> IndexedGetting i (Endo [(i, a)]) a a)
-> (i -> a -> [r] -> r) -> i -> a -> r
iparaOf forall i a. IndexedPlated i a => i -> IndexedTraversal' i a a
iplate
{-# INLINE ipara #-}

-- | Perform a fold-like computation on each value within a container, using the
-- provided lens to locate immediate children.
--
-- @since 0.1.0
iparaOf :: (i -> IndexedGetting i (Endo [(i, a)]) a a) -> (i -> a -> [r] -> r) -> i -> a -> r
iparaOf :: forall i a r.
(i -> IndexedGetting i (Endo [(i, a)]) a a)
-> (i -> a -> [r] -> r) -> i -> a -> r
iparaOf i -> IndexedGetting i (Endo [(i, a)]) a a
l i -> a -> [r] -> r
f = i -> a -> r
go
  where
    go :: i -> a -> r
go i
i a
a = i -> a -> [r] -> r
f i
i a
a [i -> a -> r
go i
j a
b | (i
j, a
b) <- forall i a s. IndexedGetting i (Endo [(i, a)]) s a -> s -> [(i, a)]
itoListOf (i -> IndexedGetting i (Endo [(i, a)]) a a
l i
i) a
a]
{-# INLINE iparaOf #-}