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-extra-0.4.2.1Haskell2010

Optics.Indexed

This module defines general 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.

Unlike Optics.Indexed.Core, this includes the definitions from modules for specific indexed optic flavours such as Optics.IxTraversal, and includes additional instances for FunctorWithIndex and similar classes.

  • 24 types
  • 7 classes
  • 86 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

9 declarations
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

99 declarations
datadata An_AffineFold
#

Tag for an affine fold.

Instances29Is, ViewableOptic, JoinKinds, IxOptic, ToReadOnly, ReadOnlyOptic, …
datadata An_AffineTraversal
#

Tag for an affine traversal.

Instances33Is, ArrowOptic, ViewableOptic, PermeableOptic, JoinKinds, IxOptic, …
typetype IxAffineTraversalVL i s t a b = forall (f :: Type -> Type). Functor f => (forall r. r -> f r) -> (i -> a -> f b) -> s -> f t
#

Type synonym for a type-modifying van Laarhoven indexed affine traversal.

Note: this isn't exactly van Laarhoven representation as there is no Pointed class (which would be a superclass of Applicative that contains pure but not <*>). You can interpret the first argument as a dictionary of Pointed that supplies the point function (i.e. the implementation of pure).

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
    
Instances32FoldableWithIndex, …
datadata A_Fold
#

Tag for a fold.

Instances30Is, ViewableOptic, JoinKinds, IxOptic, ToReadOnly, ReadOnlyOptic, …
valueifailing
  1. :: (Is k A_Fold, Is l A_Fold, HasSingleIndex is1 i, HasSingleIndex is2 i)
  2. => Optic' k is1 s a
  3. -> Optic' l is2 s a
  4. -> IxFold i s a
#

Try the first IxFold. If it returns no entries, try the second one.

Example2 expressions
itoListOf (_1 % ifolded `ifailing` _2 % ifolded) (["a"], ["b","c"])[(0,"a")]itoListOf (_1 % ifolded `ifailing` _2 % ifolded) ([], ["b","c"])[(0,"b"),(1,"c")]
valueifindMOf
  1. :: (Is k A_Fold, Monad m, HasSingleIndex is i)
  2. => Optic' k is s a
  3. -> i -> a -> m Bool
  4. -> s
  5. -> m (Maybe (i, a))
#

The ifindMOf function takes an IxFold, a monadic predicate that is also supplied the index, a structure and returns in the monad 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 findMOf is more flexible in what it accepts.

valueifindOf
  1. :: (Is k A_Fold, HasSingleIndex is i)
  2. => Optic' k is s a
  3. -> i -> a -> Bool
  4. -> s
  5. -> Maybe (i, a)
#

The ifindOf function takes an IxFold, a predicate that is also supplied the index, a structure and returns the left-most element of the structure along with its index matching the predicate, or Nothing if there is no such element.

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

valueifolding :: FoldableWithIndex i f => (s -> f a) -> IxFold i s a
#

Obtain an IxFold by lifting an operation that returns a FoldableWithIndex result.

This can be useful to lift operations from Data.List and elsewhere into an IxFold.

Example1 expression
itoListOf (ifolding words) "how are you"[(0,"how"),(1,"are"),(2,"you")]
valueifoldring
  1. :: forall (f :: Type -> Type). Applicative f => (i -> a -> f u -> f u) -> f v -> s -> f w
  2. -> IxFold i s a
#

Obtain an IxFold by lifting ifoldr like function.

Example1 expression
itoListOf (ifoldring ifoldr) "hello"[(0,'h'),(1,'e'),(2,'l'),(3,'l'),(4,'o')]
valueitoListOf
  1. :: (Is k A_Fold, HasSingleIndex is i)
  2. => Optic' k is s a
  3. -> s
  4. -> [(i, a)]
#

Fold with index to a list.

Example1 expression
itoListOf (folded % ifolded) ["abc", "def"][(0,'a'),(1,'b'),(2,'c'),(0,'d'),(1,'e'),(2,'f')]

Note: currently indexed optics can be used as non-indexed.

Example1 expression
toListOf (folded % ifolded) ["abc", "def"]"abcdef"
datadata A_Getter
#

Tag for a getter.

Instances31ReversibleOptic, Is, ViewableOptic, JoinKinds, IxOptic, ToReadOnly, …
valueito :: (s -> (i, a)) -> IxGetter i s a
#

Build an indexed getter from a function.

Example1 expression
iview (ito id) ('i', 'x')('i','x')
datadata A_Lens
#

Tag for a lens.

Instances38ReversibleOptic, Is, ArrowOptic, ViewableOptic, PermeableOptic, JoinKinds, …
typetype IxLensVL i s t a b = forall (f :: Type -> Type). Functor f => (i -> a -> f b) -> s -> f t
#

Type synonym for a type-modifying van Laarhoven indexed lens.

typetype IxLensVL' i s a = IxLensVL i s s a a
#

Type synonym for a type-preserving van Laarhoven indexed lens.

valuedevoid :: IxLens' i Void a
#

There is an indexed field for every type in the Void.

Example1 expression
set (mapped % devoid) 1 [][]
Example1 expression
over (_Just % devoid) abs NothingNothing
valueifst :: IxLens i (a, i) (b, i) a b
#

Indexed _1 with other half of a pair as an index.

See isnd for examples.

valueilens :: (s -> (i, a)) -> (s -> b -> t) -> IxLens i s t a b
#

Build an indexed lens from a getter and a setter.

If you want to build an IxLens from the van Laarhoven representation, use ilensVL.

valueilensVL :: IxLensVL i s t a b -> IxLens i s t a b
#

Build an indexed lens from the van Laarhoven representation.

valueisnd :: IxLens i (i, a) (i, b) a b
#

Indexed _2 with other half of a pair as an index. Specialized version of itraversed to pairs, which can be IxLens.

Example1 expression
iview isnd ('a', True)('a',True)

That is not possible with itraversed, because it is an IxTraversal.

Example1 expression
:t itraversed :: IxTraversal i (i, a) (i, b) a bitraversed :: IxTraversal i (i, a) (i, b) a b  :: IxTraversal i (i, a) (i, b) a b
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.

Instances34FunctorWithIndex, …
datadata A_Setter
#

Tag for a setter.

Instances17Is, JoinKinds, IxOptic, …
valueisets :: ((i -> a -> b) -> s -> t) -> IxSetter i s t a b
#

Build an indexed setter from a function to modify the element(s).

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

Instances32TraversableWithIndex, …
datadata A_Traversal
#

Tag for a traversal.

Instances31Is, ViewableOptic, PermeableOptic, JoinKinds, IxOptic, ToReadOnly, …
valueitraverseOf
  1. :: (Is k A_Traversal, Applicative f, HasSingleIndex is i)
  2. => Optic k is s t a b
  3. -> i -> a -> f b
  4. -> s
  5. -> f t
#

Map each element of a structure targeted by an IxTraversal (supplying the index), evaluate these actions from left to right, and collect the results.

This yields the van Laarhoven representation of an indexed traversal.

typetype IxTraversalVL i s t a b = forall (f :: Type -> Type). Applicative f => (i -> a -> f b) -> s -> f t
#

Type synonym for a type-modifying van Laarhoven indexed traversal.

valueiadjoin
  1. :: (Is k A_Traversal, Is l A_Traversal, HasSingleIndex is i)
  2. => Optic' k is s a
  3. -> Optic' l is s a
  4. -> IxTraversal' i s a
#

Combine two disjoint indexed traversals into one.

Example1 expression
iover (_1 % itraversed `iadjoin` _2 % itraversed) (+) ([0, 0, 0], (3, 5))([0,1,2],(3,8))

Note: if the argument traversals are not disjoint, the result will not respect the IxTraversal laws, because it will visit the same element multiple times. See section 7 of Understanding Idiomatic Traversals Backwards and Forwards by Bird et al. for why this is illegal.

Example2 expressions
iview (ipartsOf (each `iadjoin` each)) ("x","y")([0,1,0,1],["x","y","x","y"])iset (ipartsOf (each `iadjoin` each)) (const ["a","b","c","d"]) ("x","y")("c","d")

For the IxFold version see isumming.

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.

Instances34FunctorWithIndex, …

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

Instances32TraversableWithIndex, …