HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleoptics-core-0.4.1.1Haskell2010

Optics.Indexed.Core

This module defines basic functionality for indexed optics. See the "Indexed optics" section of the overview documentation in the Optics module of the main optics package for more details.

  • 4 classes
  • 15 values

Class for optic kinds that can be indexed

2 declarations
classclass IxOptic (k :: OpticKind) s t a b where
#

Class for optic kinds that can have indices.

Methods

Instances7IxOptic, …
valueconjoined
  1. :: HasSingleIndex is i
  2. => Optic k NoIx s t a b
  3. -> Optic k is s t a b
  4. -> Optic k is s t a b
#

Construct a conjoined indexed optic that provides a separate code path when used without indices. Useful for defining indexed optics that are as efficient as their unindexed equivalents when used without indices.

Note: conjoined f g is well-defined if and only if f ≡ noIx g.

Composition of indexed optics

10 declarations
value(%)
  1. :: (JoinKinds k l m, AppendIndices is js ks)
  2. => Optic k is s t u v
  3. -> Optic l js u v a b
  4. -> Optic m ks s t a b
#

Compose two optics of compatible flavours.

Returns an optic of the appropriate supertype. If either or both optics are indexed, the composition preserves all the indices.

value(<%>)
  1. :: (JoinKinds k l m, IxOptic m s t a b, HasSingleIndex is i, HasSingleIndex js j)
  2. => Optic k is s t u v
  3. -> Optic l js u v a b
  4. -> Optic m (WithIx (i, j)) s t a b
#

Compose two indexed optics. Their indices are composed as a pair.

Example1 expression
itoListOf (ifolded <%> ifolded) ["foo", "bar"][((0,0),'f'),((0,1),'o'),((0,2),'o'),((1,0),'b'),((1,1),'a'),((1,2),'r')]
value(%>)
  1. :: (JoinKinds k l m, IxOptic k s t u v, NonEmptyIndices is)
  2. => Optic k is s t u v
  3. -> Optic l js u v a b
  4. -> Optic m js s t a b
#

Compose two indexed optics and drop indices of the left one. (If you want to compose a non-indexed and an indexed optic, you can just use (%).)

Example1 expression
itoListOf (ifolded %> ifolded) ["foo", "bar"][(0,'f'),(1,'o'),(2,'o'),(0,'b'),(1,'a'),(2,'r')]
value(<%)
  1. :: (JoinKinds k l m, IxOptic l u v a b, NonEmptyIndices js)
  2. => Optic k is s t u v
  3. -> Optic l js u v a b
  4. -> Optic m is s t a b
#

Compose two indexed optics and drop indices of the right one. (If you want to compose an indexed and a non-indexed optic, you can just use (%).)

Example1 expression
itoListOf (ifolded <% ifolded) ["foo", "bar"][(0,'f'),(0,'o'),(0,'o'),(1,'b'),(1,'a'),(1,'r')]
valuereindexed
  1. :: HasSingleIndex is i
  2. => i -> j
  3. -> Optic k is s t a b
  4. -> Optic k (WithIx j) s t a b
#

Remap the index.

Example1 expression
itoListOf (reindexed succ ifolded) "foo"[(1,'f'),(2,'o'),(3,'o')]
Example1 expression
itoListOf (ifolded %& reindexed succ) "foo"[(1,'f'),(2,'o'),(3,'o')]
valueicompose
  1. :: i -> j -> ix
  2. -> Optic k '[i, j] s t a b
  3. -> Optic k (WithIx ix) s t a b
#

Flatten indices obtained from two indexed optics.

Example1 expression
itoListOf (ifolded % ifolded %& icompose (,)) ["foo","bar"][((0,0),'f'),((0,1),'o'),((0,2),'o'),((1,0),'b'),((1,1),'a'),((1,2),'r')]
valueicompose3
  1. :: i1 -> i2 -> i3 -> ix
  2. -> Optic k '[i1, i2, i3] s t a b
  3. -> Optic k (WithIx ix) s t a b
#

Flatten indices obtained from three indexed optics.

Example1 expression
itoListOf (ifolded % ifolded % ifolded %& icompose3 (,,)) [["foo","bar"],["xyz"]][((0,0,0),'f'),((0,0,1),'o'),((0,0,2),'o'),((0,1,0),'b'),((0,1,1),'a'),((0,1,2),'r'),((1,0,0),'x'),((1,0,1),'y'),((1,0,2),'z')]
valueicompose4
  1. :: i1 -> i2 -> i3 -> i4 -> ix
  2. -> Optic k '[i1, i2, i3, i4] s t a b
  3. -> Optic k (WithIx ix) s t a b
#

Flatten indices obtained from four indexed optics.

valueicompose5
  1. :: i1 -> i2 -> i3 -> i4 -> i5 -> ix
  2. -> Optic k '[i1, i2, i3, i4, i5] s t a b
  3. -> Optic k (WithIx ix) s t a b
#

Flatten indices obtained from five indexed optics.

Indexed optic flavours

0 declarations

Functors with index

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.

Instances30FunctorWithIndex, …

Foldable with index

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
    
Instances28FoldableWithIndex, …
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
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

Traversable with index

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

Instances28TraversableWithIndex, …