HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Modulelens-5.3.5Haskell2010

Control.Lens.Indexed

(The classes in here need to be defined together for DefaultSignatures to work.)

  • 1 type
  • 5 classes
  • 37 values
  • Packagelens-5.3.5
  • Exports43
  • LanguageHaskell2010
  • LicenceBSD-2-Clause
  • SourceIndexed.hs

Indexing

11 declarations
classclass Conjoined p => Indexable i (p :: Type -> Type -> Type) where
#

This class permits overloading of function application for things that also admit a notion of a key or index.

Methods

  • indexed :: p a b -> i -> a -> b

    Build a function from an indexed function.

Instances2Indexable
  • i ~ j => Indexable i (Indexed j)Defined in lens-5.3.5 · Control.Lens.Internal.Indexed
  • Indexable i (->)Defined in lens-5.3.5 · Control.Lens.Internal.Indexed
classclass (Choice p, Corepresentable p, Comonad (Corep p), Traversable (Corep p), Strong p, Representable p, Monad (Rep p), MonadFix (Rep p), Distributive (Rep p), Costrong p, ArrowLoop p, ArrowApply p, ArrowChoice p, Closed p) => Conjoined (p :: Type -> Type -> Type) where
#

This is a Profunctor that is both Corepresentable by f and Representable by g such that f is left adjoint to g. From this you can derive a lot of structure due to the preservation of limits and colimits.

Methods

  • distrib :: Functor f => p a b -> p (f a) (f b)

    Conjoined is strong enough to let us distribute every Conjoined Profunctor over every Haskell Functor. This is effectively a generalization of fmap.

  • conjoined :: (p ~ (->) => q (a -> b) r) -> q (p a b) r -> q (p a b) r

    This permits us to make a decision at an outermost point about whether or not we use an index.

    Ideally any use of this function should be done in such a way so that you compute the same answer, but this cannot be enforced at the type level.

Instances3Conjoined
newtypenewtype Indexed i a b
#

A function with access to a index. This constructor may be useful when you need to store an Indexable in a container to avoid ImpredicativeTypes.

index :: Indexed i a b -> i -> a -> b

Constructors

Instances27Category, Indexable, Arrow, ArrowApply, ArrowChoice, ArrowLoop, …
value(<.)
  1. :: Indexable i p
  2. => Indexed i s t -> r
  3. -> (a -> b) -> s -> t
  4. -> p a b
  5. -> r
#

Compose an Indexed function with a non-indexed function.

Mnemonically, the < points to the indexing we want to preserve.

Example2 expressions
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")]
value(<.>)
  1. :: Indexable (i, j) p
  2. => Indexed i s t -> r
  3. -> Indexed j a b -> s -> t
  4. -> p a b
  5. -> r
#

Composition of Indexed functions.

Mnemonically, the < and > points to the fact that we want to preserve the indices.

Example2 expressions
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")]
value(.>) :: (st -> r) -> (kab -> st) -> kab -> r
#

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.

Example2 expressions
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")]
valueselfIndex :: Indexable a p => p a fb -> a -> fb
#

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
valueindexing
  1. :: Indexable Int p
  2. => (a -> Indexing f b) -> s -> Indexing f t
  3. -> p a (f b)
  4. -> s
  5. -> f t
#

Transform a Control.Lens.Traversal.Traversal into an Control.Lens.Traversal.IndexedTraversal or a Control.Lens.Fold.Fold into an Control.Lens.Fold.IndexedFold, etc.

indexing :: Traversal s t a b -> IndexedTraversal Int s t a b
indexing :: Prism s t a b     -> IndexedTraversal Int s t a b
indexing :: Lens s t a b      -> IndexedLens Int  s t a b
indexing :: Iso s t a b       -> IndexedLens Int s t a b
indexing :: Fold s a          -> IndexedFold Int s a
indexing :: Getter s a        -> IndexedGetter Int s a
indexing :: Indexable Int p => LensLike (Indexing f) s t a b -> Over p f s t a b
valueindexing64
  1. :: Indexable Int64 p
  2. => (a -> Indexing64 f b) -> s -> Indexing64 f t
  3. -> p a (f b)
  4. -> s
  5. -> f t
#

Transform a Control.Lens.Traversal.Traversal into an Control.Lens.Traversal.IndexedTraversal or a Control.Lens.Fold.Fold into an Control.Lens.Fold.IndexedFold, etc.

This combinator is like indexing except that it handles large traversals and folds gracefully.

indexing64 :: Traversal s t a b -> IndexedTraversal Int64 s t a b
indexing64 :: Prism s t a b     -> IndexedTraversal Int64 s t a b
indexing64 :: Lens s t a b      -> IndexedLens Int64 s t a b
indexing64 :: Iso s t a b       -> IndexedLens Int64 s t a b
indexing64 :: Fold s a          -> IndexedFold Int64 s a
indexing64 :: Getter s a        -> IndexedGetter Int64 s a
indexing64 :: Indexable Int64 p => LensLike (Indexing64 f) s t a b -> Over p f s t a b

Indexed Functors

1 declaration
classclass Functor f => FunctorWithIndex i (f :: Type -> Type) | f -> i where
#

A Functor with an additional index.

Instances must satisfy a modified form of the Functor laws:

imap f . imap g ≡ imap (\i -> f i . g i)
imap (\_ a -> a) ≡ id

Methods

  • imap :: (i -> a -> b) -> f a -> f b

    Map with access to the index.

Instances40FunctorWithIndex, …

Indexed Functor Combinators

Indexed Foldables

1 declaration
classclass Foldable f => FoldableWithIndex i (f :: Type -> Type) | f -> i where
#

A container that supports folding with an additional index.

Methods

  • ifoldMap :: Monoid m => (i -> a -> m) -> f a -> m

    Fold a container by mapping value to an arbitrary Monoid with access to the index i.

    When you don't need access to the index then foldMap is more flexible in what it accepts.

    foldMap ≡ ifoldMap . const
    
  • ifoldMap' :: Monoid m => (i -> a -> m) -> f a -> m

    A variant of ifoldMap that is strict in the accumulator.

    When you don't need access to the index then foldMap' is more flexible in what it accepts.

    foldMap' ≡ ifoldMap' . const
    
  • ifoldr :: (i -> a -> b -> b) -> b -> f a -> b

    Right-associative fold of an indexed container with access to the index i.

    When you don't need access to the index then foldr is more flexible in what it accepts.

    foldr ≡ ifoldr . const
    
  • ifoldl :: (i -> b -> a -> b) -> b -> f a -> b

    Left-associative fold of an indexed container with access to the index i.

    When you don't need access to the index then foldl is more flexible in what it accepts.

    foldl ≡ ifoldl . const
    
  • ifoldr' :: (i -> a -> b -> b) -> b -> f a -> b

    Strictly fold right over the elements of a structure with access to the index i.

    When you don't need access to the index then foldr' is more flexible in what it accepts.

    foldr' ≡ ifoldr' . const
    
  • ifoldl' :: (i -> b -> a -> b) -> b -> f a -> b

    Fold over the elements of a structure with an index, associating to the left, but strictly.

    When you don't need access to the index then foldlOf' is more flexible in what it accepts.

    foldl' l ≡ ifoldl' l . const
    
Instances37FoldableWithIndex, …

Indexed Foldable Combinators

valueiany :: FoldableWithIndex i f => (i -> a -> Bool) -> f a -> Bool
#

Return whether or not any element in a container satisfies a predicate, with access to the index i.

When you don't need access to the index then any is more flexible in what it accepts.

any ≡ iany . const
valueiall :: FoldableWithIndex i f => (i -> a -> Bool) -> f a -> Bool
#

Return whether or not all elements in a container satisfy a predicate, with access to the index i.

When you don't need access to the index then all is more flexible in what it accepts.

all ≡ iall . const
valueinone :: FoldableWithIndex i f => (i -> a -> Bool) -> f a -> Bool
#

Return whether or not none of the elements in a container satisfy a predicate, with access to the index i.

When you don't need access to the index then none is more flexible in what it accepts.

none ≡ inone . const
inone f ≡ not . iany f
valueitraverse_
  1. :: (FoldableWithIndex i t, Applicative f)
  2. => i -> a -> f b
  3. -> t a
  4. -> f ()
#

Traverse elements with access to the index i, discarding the results.

When you don't need access to the index then traverse_ is more flexible in what it accepts.

traverse_ l = itraverse . const
valueifor_
  1. :: (FoldableWithIndex i t, Applicative f)
  2. => t a
  3. -> i -> a -> f b
  4. -> f ()
#

Traverse elements with access to the index i, discarding the results (with the arguments flipped).

ifor_ ≡ flip itraverse_

When you don't need access to the index then for_ is more flexible in what it accepts.

for_ a ≡ ifor_ a . const
valueimapM_ :: (FoldableWithIndex i t, Monad m) => (i -> a -> m b) -> t a -> m ()
#

Run monadic actions for each target of an IndexedFold or Control.Lens.IndexedTraversal.IndexedTraversal with access to the index, discarding the results.

When you don't need access to the index then mapMOf_ is more flexible in what it accepts.

mapM_ ≡ imapM . const
valueiforM_ :: (FoldableWithIndex i t, Monad m) => t a -> (i -> a -> m b) -> m ()
#

Run monadic actions for each target of an IndexedFold or Control.Lens.IndexedTraversal.IndexedTraversal with access to the index, discarding the results (with the arguments flipped).

iforM_ ≡ flip imapM_

When you don't need access to the index then forM_ is more flexible in what it accepts.

forM_ a ≡ iforM a . const
valueiconcatMap :: FoldableWithIndex i f => (i -> a -> [b]) -> f a -> [b]
#

Concatenate the results of a function of the elements of an indexed container with access to the index.

When you don't need access to the index then concatMap is more flexible in what it accepts.

concatMap ≡ iconcatMap . const
iconcatMap ≡ ifoldMap
valueifind :: FoldableWithIndex i f => (i -> a -> Bool) -> f a -> Maybe (i, a)
#

Searches a container with a predicate that is also supplied the index, returning the left-most element of the structure matching the predicate, or Nothing if there is no such element.

When you don't need access to the index then find is more flexible in what it accepts.

find ≡ ifind . const
valueifoldrM
  1. :: (FoldableWithIndex i f, Monad m)
  2. => i -> a -> b -> m b
  3. -> b
  4. -> f a
  5. -> m b
#

Monadic fold right over the elements of a structure with an index.

When you don't need access to the index then foldrM is more flexible in what it accepts.

foldrM ≡ ifoldrM . const
valueifoldlM
  1. :: (FoldableWithIndex i f, Monad m)
  2. => i -> b -> a -> m b
  3. -> b
  4. -> f a
  5. -> m b
#

Monadic fold over the elements of a structure with an index, associating to the left.

When you don't need access to the index then foldlM is more flexible in what it accepts.

foldlM ≡ ifoldlM . const
valueitoList :: FoldableWithIndex i f => f a -> [(i, a)]
#

Extract the key-value pairs from a structure.

When you don't need access to the indices in the result, then toList is more flexible in what it accepts.

toList ≡ map snd . itoList

Converting to Folds

2 declarations
valuewithIndex
  1. :: (Indexable i p, Functor f)
  2. => p (i, s) (f (j, t))
  3. -> Indexed i s (f t)
#

Fold a container with indices returning both the indices and the values.

The result is only valid to compose in a Traversal, if you don't edit the index as edits to the index have no effect.

Example1 expression
[10, 20, 30] ^.. ifolded . withIndex[(0,10),(1,20),(2,30)]
Example1 expression
[10, 20, 30] ^.. ifolded . withIndex . alongside negated (re _Show)[(0,"10"),(-1,"20"),(-2,"30")]

Restricting by Index

2 declarations

Indexed Traversables

1 declaration
classclass (FunctorWithIndex i t, FoldableWithIndex i t, Traversable t) => TraversableWithIndex i (t :: Type -> Type) | t -> i where
#

A Traversable with an additional index.

An instance must satisfy a (modified) form of the Traversable laws:

itraverse (const Identity) ≡ Identity
fmap (itraverse f) . itraverse g ≡ getCompose . itraverse (\i -> Compose . fmap (f i) . g i)

Methods

Instances37TraversableWithIndex, …

Indexed Traversable Combinators

6 declarations
valueimapM
  1. :: (TraversableWithIndex i t, Monad m)
  2. => i -> a -> m b
  3. -> t a
  4. -> m (t b)
#

Map each element of a structure to a monadic action, evaluate these actions from left to right, and collect the results, with access the index.

When you don't need access to the index mapM is more liberal in what it can accept.

mapM ≡ imapM . const
valueiforM
  1. :: (TraversableWithIndex i t, Monad m)
  2. => t a
  3. -> i -> a -> m b
  4. -> m (t b)
#

Map each element of a structure to a monadic action, evaluate these actions from left to right, and collect the results, with access its position (and the arguments flipped).

forM a ≡ iforM a . const
iforM ≡ flip imapM
valueimapAccumR
  1. :: TraversableWithIndex i t
  2. => i -> s -> a -> (s, b)
  3. -> s
  4. -> t a
  5. -> (s, t b)
#

Generalizes Data.Traversable.mapAccumR to add access to the index.

imapAccumR accumulates state from right to left.

Data.Traversable.mapAccumR ≡ imapAccumR . const
valueimapAccumL
  1. :: TraversableWithIndex i t
  2. => i -> s -> a -> (s, b)
  3. -> s
  4. -> t a
  5. -> (s, t b)
#

Generalizes Data.Traversable.mapAccumL to add access to the index.

imapAccumL accumulates state from left to right.

Data.Traversable.mapAccumL ≡ imapAccumL . const

Indexed Folds with Reified Monoid

2 declarations

Indexed Traversals with Reified Applicative

2 declarations