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

A Traversal s t a b is a generalization of traverse from Traversable. It allows you to traverse over a structure and change out its contents with monadic or Applicative side-effects. Starting from

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

we monomorphize the contents and result to obtain

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t

A Traversal can be used as a Fold. Any Traversal can be used for Getting like a Fold, because given a Monoid m, we have an Applicative for (Const m). Everything you know how to do with a Traversable container, you can with a Traversal, and here we provide combinators that generalize the usual Traversable operations.

  • 24 types
  • 4 classes
  • 60 values
  • Packagelens-5.3.5
  • Exports88
  • LanguageHaskell2010
  • LicenceBSD-2-Clause
  • SourceTraversal.hs

Traversals

20 declarations
typetype Traversal s t a b = forall (f :: Type -> Type). Applicative f => (a -> f b) -> s -> f t
#

A Traversal can be used directly as a Control.Lens.Setter.Setter or a Fold (but not as a Lens) and provides the ability to both read and update multiple fields, subject to some relatively weak Traversal laws.

These have also been known as multilenses, but they have the signature and spirit of

traverse :: Traversable f => Traversal (f a) (f b) a b

and the more evocative name suggests their application.

Most of the time the Traversal you will want to use is just traverse, but you can also pass any Lens or Iso as a Traversal, and composition of a Traversal (or Lens or Iso) with a Traversal (or Lens or Iso) using (.) forms a valid Traversal.

The laws for a Traversal t follow from the laws for Traversable as stated in "The Essence of the Iterator Pattern".

t pure ≡ pure
fmap (t f) . t g ≡ getCompose . t (Compose . fmap f . g)

One consequence of this requirement is that a Traversal needs to leave the same number of elements as a candidate for subsequent Traversal that it started with. Another testament to the strength of these laws is that the caveat expressed in section 5.5 of the "Essence of the Iterator Pattern" about exotic Traversable instances that traverse the same entry multiple times was actually already ruled out by the second law in that same paper!

typetype IndexedTraversal i s t a b = forall (p :: Type -> Type -> Type) (f :: Type -> Type). (Indexable i p, Applicative f) => p a (f b) -> s -> f t
#

Every IndexedTraversal is a valid Traversal or Control.Lens.Fold.IndexedFold.

The Indexed constraint is used to allow an IndexedTraversal to be used directly as a Traversal.

The Traversal laws are still required to hold.

In addition, the index i should satisfy the requirement that it stays unchanged even when modifying the value a, otherwise traversals like indices break the Traversal laws.

Traversing and Lensing

14 declarations
valuetraversal :: ((a -> f b) -> s -> f t) -> LensLike f s t a b
#

Build a Traversal by providing a function which specifies the elements you wish to focus.

The caller provides a function of type:

Applicative f => (a -> f b) -> s -> f t

Which is a higher order function which accepts a "focusing function" and applies it to all desired focuses within s, then constructs a t using the Applicative instance of f.

Only elements which are "focused" using the focusing function will be targeted by the resulting traversal.

For example, we can explicitly write a traversal which targets the first and third elements of a tuple like this:

firstAndThird :: Traversal (a, x, a) (b, x, b) a b
firstAndThird = traversal go
  where
    go :: Applicative f => (a -> f b) -> (a, x, a) -> f (b, x, b)
    go focus (a, x, a') = liftA3 (,,) (focus a) (pure x) (focus a')
Example1 expression
(1,"two",3) & firstAndThird *~ 10(10,"two",30)
Example1 expression
over firstAndThird length ("one",2,"three")(3,2,5)

We can re-use existing Traversals when writing new ones by passing our focusing function along to them. This example re-uses traverse to focus all elements in a list which is embedded in a tuple. This traversal could also be written simply as _2 . traverse.

selectNested :: Traversal (x, [a]) (x, [b]) a b
selectNested = traversal go
  where
    go :: Applicative f => (a -> f b) -> (x, [a]) -> f (x, [b])
    go focus (x, as) = liftA2 (,) (pure x) (traverse focus as)
Example1 expression
selectNested .~ "hello" $ (1,[2,3,4,5])(1,["hello","hello","hello","hello"])
Example1 expression
(1,[2,3,4,5]) & selectNested *~ 3(1,[6,9,12,15])

Note that the traversal function actually just returns the same function you pass to it. The function it accepts is in fact a valid traversal all on its own! The use of traversal does nothing except verify that the function it is passed matches the signature of a valid traversal. One could remove the traversal combinator from either of the last two examples and use the definition of go directly with no change in behaviour.

This function exists for consistency with the lens, prism and iso constructors as well as to serve as a touchpoint for beginners who wish to construct their own traversals but are uncertain how to do so.

valuetraverseOf :: LensLike f s t a b -> (a -> f b) -> s -> f t
#

Map each element of a structure targeted by a Lens or Traversal, evaluate these actions from left to right, and collect the results.

This function is only provided for consistency, id is strictly more general.

Example1 expression
traverseOf each print (1,2,3)123((),(),())
traverseOf ≡ id
itraverseOf l ≡ traverseOf l . Indexed
itraverseOf itraversed ≡ itraverse

This yields the obvious law:

traverse ≡ traverseOf traverse
traverseOf :: Functor f     => Iso s t a b        -> (a -> f b) -> s -> f t
traverseOf :: Functor f     => Lens s t a b       -> (a -> f b) -> s -> f t
traverseOf :: Apply f       => Traversal1 s t a b -> (a -> f b) -> s -> f t
traverseOf :: Applicative f => Traversal s t a b  -> (a -> f b) -> s -> f t
valueforOf :: LensLike f s t a b -> s -> (a -> f b) -> f t
#

A version of traverseOf with the arguments flipped, such that:

Example1 expression
forOf each (1,2,3) print123((),(),())

This function is only provided for consistency, flip is strictly more general.

forOf ≡ flip
forOf ≡ flip . traverseOf
for ≡ forOf traverse
ifor l s ≡ for l s . Indexed
forOf :: Functor f => Iso s t a b -> s -> (a -> f b) -> f t
forOf :: Functor f => Lens s t a b -> s -> (a -> f b) -> f t
forOf :: Applicative f => Traversal s t a b -> s -> (a -> f b) -> f t
valuemapMOf :: LensLike (WrappedMonad m) s t a b -> (a -> m b) -> s -> m t
#

Map each element of a structure targeted by a Lens to a monadic action, evaluate these actions from left to right, and collect the results.

Example1 expression
mapMOf both (\x -> [x, x + 1]) (1,3)[(1,3),(1,4),(2,3),(2,4)]
mapM ≡ mapMOf traverse
imapMOf l ≡ forM l . Indexed
mapMOf :: Monad m => Iso s t a b       -> (a -> m b) -> s -> m t
mapMOf :: Monad m => Lens s t a b      -> (a -> m b) -> s -> m t
mapMOf :: Monad m => Traversal s t a b -> (a -> m b) -> s -> m t
valueforMOf :: LensLike (WrappedMonad m) s t a b -> s -> (a -> m b) -> m t
#

forMOf is a flipped version of mapMOf, consistent with the definition of forM.

Example1 expression
forMOf both (1,3) $ \x -> [x, x + 1][(1,3),(1,4),(2,3),(2,4)]
forM ≡ forMOf traverse
forMOf l ≡ flip (mapMOf l)
iforMOf l s ≡ forM l s . Indexed
forMOf :: Monad m => Iso s t a b       -> s -> (a -> m b) -> m t
forMOf :: Monad m => Lens s t a b      -> s -> (a -> m b) -> m t
forMOf :: Monad m => Traversal s t a b -> s -> (a -> m b) -> m t
valuesequenceOf :: LensLike (WrappedMonad m) s t (m b) b -> s -> m t
#

Sequence the (monadic) effects targeted by a Lens in a container from left to right.

Example1 expression
sequenceOf each ([1,2],[3,4],[5,6])[(1,3,5),(1,3,6),(1,4,5),(1,4,6),(2,3,5),(2,3,6),(2,4,5),(2,4,6)]
sequence ≡ sequenceOf traverse
sequenceOf l ≡ mapMOf l id
sequenceOf l ≡ unwrapMonad . l WrapMonad
sequenceOf :: Monad m => Iso s t (m b) b       -> s -> m t
sequenceOf :: Monad m => Lens s t (m b) b      -> s -> m t
sequenceOf :: Monad m => Traversal s t (m b) b -> s -> m t
valuemapAccumLOf
  1. :: LensLike (State acc) s t a b
  2. -> acc -> a -> (acc, b)
  3. -> acc
  4. -> s
  5. -> (acc, t)
#

This generalizes Data.Traversable.mapAccumL to an arbitrary Traversal.

mapAccumL ≡ mapAccumLOf traverse

mapAccumLOf accumulates State from left to right.

mapAccumLOf :: Iso s t a b       -> (acc -> a -> (acc, b)) -> acc -> s -> (acc, t)
mapAccumLOf :: Lens s t a b      -> (acc -> a -> (acc, b)) -> acc -> s -> (acc, t)
mapAccumLOf :: Traversal s t a b -> (acc -> a -> (acc, b)) -> acc -> s -> (acc, t)
mapAccumLOf :: LensLike (State acc) s t a b -> (acc -> a -> (acc, b)) -> acc -> s -> (acc, t)
mapAccumLOf l f acc0 s = swap (runState (l (a -> state (acc -> swap (f acc a))) s) acc0)
valuemapAccumROf
  1. :: LensLike (Backwards (State acc)) s t a b
  2. -> acc -> a -> (acc, b)
  3. -> acc
  4. -> s
  5. -> (acc, t)
#

This generalizes Data.Traversable.mapAccumR to an arbitrary Traversal.

mapAccumR ≡ mapAccumROf traverse

mapAccumROf accumulates State from right to left.

mapAccumROf :: Iso s t a b       -> (acc -> a -> (acc, b)) -> acc -> s -> (acc, t)
mapAccumROf :: Lens s t a b      -> (acc -> a -> (acc, b)) -> acc -> s -> (acc, t)
mapAccumROf :: Traversal s t a b -> (acc -> a -> (acc, b)) -> acc -> s -> (acc, t)
mapAccumROf :: LensLike (Backwards (State acc)) s t a b -> (acc -> a -> (acc, b)) -> acc -> s -> (acc, t)
valuefailover
  1. :: Alternative m
  2. => LensLike (Tuple2 Any) s t a b
  3. -> a -> b
  4. -> s
  5. -> m t
#

Try to map a function over this Traversal, failing if the Traversal has no targets.

Example1 expression
failover (element 3) (*2) [1,2] :: Maybe [Int]Nothing
Example1 expression
failover _Left (*2) (Right 4) :: Maybe (Either Int Int)Nothing
Example1 expression
failover _Right (*2) (Right 4) :: Maybe (Either Int Int)Just (Right 8)
failover :: Alternative m => Traversal s t a b -> (a -> b) -> s -> m t

Monomorphic Traversals

6 declarations
valuecloneTraversal :: ATraversal s t a b -> Traversal s t a b
#

A Traversal is completely characterized by its behavior on a Bazaar.

Cloning a Traversal is one way to make sure you aren't given something weaker, such as a Fold and can be used as a way to pass around traversals that have to be monomorphic in f.

Note: This only accepts a proper Traversal (or Lens). To clone a Lens as such, use cloneLens.

Note: It is usually better to use ReifiedTraversal and runTraversal than to cloneTraversal. The former can execute at full speed, while the latter needs to round trip through the Bazaar.

Example2 expressions
let foo l a = (view (getting (cloneTraversal l)) a, set (cloneTraversal l) 10 a)foo both ("hello","world")("helloworld",(10,10))
cloneTraversal :: LensLike (Bazaar (->) a b) s t a b -> Traversal s t a b

Parts and Holes

8 declarations
valuepartsOf :: Functor f => Traversing (->) f s t a a -> LensLike f s t [a] [a]
#

partsOf turns a Traversal into a Lens that resembles an early version of the uniplate (or biplate) type.

Note: You should really try to maintain the invariant of the number of children in the list.

Example1 expression
(a,b,c) & partsOf each .~ [x,y,z](x,y,z)

Any extras will be lost. If you do not supply enough, then the remainder will come from the original structure.

Example1 expression
(a,b,c) & partsOf each .~ [w,x,y,z](w,x,y)
Example1 expression
(a,b,c) & partsOf each .~ [x,y](x,y,c)
Example1 expression
('b', 'a', 'd', 'c') & partsOf each %~ sort('a','b','c','d')

So technically, this is only a Lens if you do not change the number of results it returns.

When applied to a Fold the result is merely a Getter.

partsOf :: Iso' s a       -> Lens' s [a]
partsOf :: Lens' s a      -> Lens' s [a]
partsOf :: Traversal' s a -> Lens' s [a]
partsOf :: Fold s a       -> Getter s [a]
partsOf :: Getter s a     -> Getter s [a]
valueunsafePartsOf
  1. :: Functor f
  2. => Traversing (->) f s t a b
  3. -> LensLike f s t [a] [b]
#

unsafePartsOf turns a Traversal into a uniplate (or biplate) family.

If you do not need the types of s and t to be different, it is recommended that you use partsOf.

It is generally safer to traverse with the Bazaar rather than use this combinator. However, it is sometimes convenient.

This is unsafe because if you don't supply at least as many b's as you were given a's, then the reconstruction of t will result in an error!

When applied to a Fold the result is merely a Getter (and becomes safe).

unsafePartsOf :: Iso s t a b       -> Lens s t [a] [b]
unsafePartsOf :: Lens s t a b      -> Lens s t [a] [b]
unsafePartsOf :: Traversal s t a b -> Lens s t [a] [b]
unsafePartsOf :: Fold s a          -> Getter s [a]
unsafePartsOf :: Getter s a        -> Getter s [a]
valueholesOf
  1. :: Conjoined p
  2. => Over p (Bazaar p a a) s t a a
  3. -> s
  4. -> [Pretext p a a t]
#

The one-level version of contextsOf. This extracts a list of the immediate children according to a given Traversal as editable contexts.

Given a context you can use pos to see the values, peek at what the structure would be like with an edited result, or simply extract the original structure.

propChildren l x = toListOf l x == map pos (holesOf l x)
propId l x = all (== x) [extract w | w <- holesOf l x]
holesOf :: Iso' s a                -> s -> [Pretext' (->) a s]
holesOf :: Lens' s a               -> s -> [Pretext' (->) a s]
holesOf :: Traversal' s a          -> s -> [Pretext' (->) a s]
holesOf :: IndexedLens' i s a      -> s -> [Pretext' (Indexed i) a s]
holesOf :: IndexedTraversal' i s a -> s -> [Pretext' (Indexed i) a s]
valueholes1Of
  1. :: Conjoined p
  2. => Over p (Bazaar1 p a a) s t a a
  3. -> s
  4. -> NonEmpty (Pretext p a a t)
#

The non-empty version of holesOf. This extract a non-empty list of immediate children according to a given Traversal1 as editable contexts.

Example2 expressions
let head1 f s = runPretext (NonEmpty.head $ holes1Of traversed1 s) f('a' :| "bc") ^. head1'a'
Example1 expression
('a' :| "bc") & head1 %~ toUpper'A' :| "bc"
holes1Of :: Iso' s a                 -> s -> NonEmpty (Pretext' (->) a s)
holes1Of :: Lens' s a                -> s -> NonEmpty (Pretext' (->) a s)
holes1Of :: Traversal1' s a          -> s -> NonEmpty (Pretext' (->) a s)
holes1Of :: IndexedLens' i s a       -> s -> NonEmpty (Pretext' (Indexed i) a s)
holes1Of :: IndexedTraversal1' i s a -> s -> NonEmpty (Pretext' (Indexed i) a s)
valuesingular
  1. :: (HasCallStack, Conjoined p, Functor f)
  2. => Traversing p f s t a a
  3. -> Over p f s t a a
#

This converts a Traversal that you "know" will target one or more elements to a Lens. It can also be used to transform a non-empty Fold into a Getter.

The resulting Lens or Getter will be partial if the supplied Traversal returns no results.

Example1 expression
[1,2,3] ^. singular _head1
Example1 expression
Left (ErrorCall "singular: empty traversal") <- try (evaluate ([] ^. singular _head)) :: IO (Either ErrorCall ())
Example1 expression
Left 4 ^. singular _Left4
Example1 expression
[1..10] ^. singular (ix 7)8
Example1 expression
[] & singular traverse .~ 0[]
singular :: Traversal s t a a          -> Lens s t a a
singular :: Fold s a                   -> Getter s a
singular :: IndexedTraversal i s t a a -> IndexedLens i s t a a
singular :: IndexedFold i s a          -> IndexedGetter i s a
valueunsafeSingular
  1. :: (HasCallStack, Conjoined p, Functor f)
  2. => Traversing p f s t a b
  3. -> Over p f s t a b
#

This converts a Traversal that you "know" will target only one element to a Lens. It can also be used to transform a Fold into a Getter.

The resulting Lens or Getter will be partial if the Traversal targets nothing or more than one element.

Example1 expression
Left (ErrorCall "unsafeSingular: empty traversal") <- try (evaluate ([] & unsafeSingular traverse .~ 0)) :: IO (Either ErrorCall [Integer])
unsafeSingular :: Traversal s t a b          -> Lens s t a b
unsafeSingular :: Fold s a                   -> Getter s a
unsafeSingular :: IndexedTraversal i s t a b -> IndexedLens i s t a b
unsafeSingular :: IndexedFold i s a          -> IndexedGetter i s a

Common Traversals

9 declarations
classclass (Functor t, Foldable t) => Traversable (t :: Type -> Type) where
#

Functors representing data structures that can be transformed to structures of the same shape by performing an Applicative (or, therefore, Monad) action on each element from left to right.

A more detailed description of what same shape means, the various methods, how traversals are constructed, and example advanced use-cases can be found in the Overview section of Data.Traversable#overview.

For the class laws see the Laws section of Data.Traversable#laws.

Methods

  • traverse :: Applicative f => (a -> f b) -> t a -> f (t b)

    Map each element of a structure to an action, evaluate these actions from left to right, and collect the results. For a version that ignores the results see traverse_.

    Examples

    Basic usage:

    In the first two examples we show each evaluated action mapping to the output structure.

    Example1 expression
    traverse Just [1,2,3,4]Just [1,2,3,4]
    Example1 expression
    traverse id [Right 1, Right 2, Right 3, Right 4]Right [1,2,3,4]

    In the next examples, we show that Nothing and Left values short circuit the created structure.

    Example1 expression
    traverse (const Nothing) [1,2,3,4]Nothing
    Example1 expression
    traverse (\x -> if odd x then Just x else Nothing)  [1,2,3,4]Nothing
    Example1 expression
    traverse id [Right 1, Right 2, Right 3, Right 4, Left 0]Left 0
Instances113Traversable, …
classclass (Foldable1 t, Traversable t) => Traversable1 (t :: Type -> Type) where
#

Methods

Instances40Traversable1, …
valueboth :: Bitraversable r => Traversal (r a a) (r b b) a b
#

Traverse both parts of a Bitraversable container with matching types.

Usually that type will be a pair. Use each to traverse the elements of arbitrary homogeneous tuples.

Example1 expression
(1,2) & both *~ 10(10,20)
Example1 expression
over both length ("hello","world")(5,5)
Example1 expression
("hello","world")^.both"helloworld"
both :: Traversal (a, a)       (b, b)       a b
both :: Traversal (Either a a) (Either b b) a b
valuebeside
  1. :: (Representable q, Applicative (Rep q), Applicative f, Bitraversable r)
  2. => Optical p q f s t a b
  3. -> Optical p q f s' t' a b
  4. -> Optical p q f (r s s') (r t t') a b
#

Apply a different Traversal or Fold to each side of a Bitraversable container.

beside :: Traversal s t a b                -> Traversal s' t' a b                -> Traversal (r s s') (r t t') a b
beside :: IndexedTraversal i s t a b       -> IndexedTraversal i s' t' a b       -> IndexedTraversal i (r s s') (r t t') a b
beside :: IndexPreservingTraversal s t a b -> IndexPreservingTraversal s' t' a b -> IndexPreservingTraversal (r s s') (r t t') a b
beside :: Traversal s t a b                -> Traversal s' t' a b                -> Traversal (s,s') (t,t') a b
beside :: Lens s t a b                     -> Lens s' t' a b                     -> Traversal (s,s') (t,t') a b
beside :: Fold s a                         -> Fold s' a                          -> Fold (s,s') a
beside :: Getter s a                       -> Getter s' a                        -> Fold (s,s') a
beside :: IndexedTraversal i s t a b       -> IndexedTraversal i s' t' a b       -> IndexedTraversal i (s,s') (t,t') a b
beside :: IndexedLens i s t a b            -> IndexedLens i s' t' a b            -> IndexedTraversal i (s,s') (t,t') a b
beside :: IndexedFold i s a                -> IndexedFold i s' a                 -> IndexedFold i (s,s') a
beside :: IndexedGetter i s a              -> IndexedGetter i s' a               -> IndexedFold i (s,s') a
beside :: IndexPreservingTraversal s t a b -> IndexPreservingTraversal s' t' a b -> IndexPreservingTraversal (s,s') (t,t') a b
beside :: IndexPreservingLens s t a b      -> IndexPreservingLens s' t' a b      -> IndexPreservingTraversal (s,s') (t,t') a b
beside :: IndexPreservingFold s a          -> IndexPreservingFold s' a           -> IndexPreservingFold (s,s') a
beside :: IndexPreservingGetter s a        -> IndexPreservingGetter s' a         -> IndexPreservingFold (s,s') a
Example1 expression
("hello",["world","!!!"])^..beside id traverse["hello","world","!!!"]
valuetaking
  1. :: (Conjoined p, Applicative f)
  2. => Int
  3. -> Traversing p f s t a a
  4. -> Over p f s t a a
#

Visit the first n targets of a Traversal, Fold, Getter or Lens.

Example1 expression
[("hello","world"),("!!!","!!!")]^.. taking 2 (traverse.both)["hello","world"]
Example1 expression
timingOut $ [1..] ^.. taking 3 traverse[1,2,3]
Example1 expression
over (taking 5 traverse) succ "hello world""ifmmp world"
taking :: Int -> Traversal' s a                   -> Traversal' s a
taking :: Int -> Lens' s a                        -> Traversal' s a
taking :: Int -> Iso' s a                         -> Traversal' s a
taking :: Int -> Prism' s a                       -> Traversal' s a
taking :: Int -> Getter s a                       -> Fold s a
taking :: Int -> Fold s a                         -> Fold s a
taking :: Int -> IndexedTraversal' i s a          -> IndexedTraversal' i s a
taking :: Int -> IndexedLens' i s a               -> IndexedTraversal' i s a
taking :: Int -> IndexedGetter i s a              -> IndexedFold i s a
taking :: Int -> IndexedFold i s a                -> IndexedFold i s a
valuedropping
  1. :: (Conjoined p, Applicative f)
  2. => Int
  3. -> Over p (Indexing f) s t a a
  4. -> Over p f s t a a
#

Visit all but the first n targets of a Traversal, Fold, Getter or Lens.

Example1 expression
("hello","world") ^? dropping 1 bothJust "world"

Dropping works on infinite traversals as well:

Example1 expression
[1..] ^? dropping 1 foldedJust 2
dropping :: Int -> Traversal' s a                   -> Traversal' s a
dropping :: Int -> Lens' s a                        -> Traversal' s a
dropping :: Int -> Iso' s a                         -> Traversal' s a
dropping :: Int -> Prism' s a                       -> Traversal' s a
dropping :: Int -> Getter s a                       -> Fold s a
dropping :: Int -> Fold s a                         -> Fold s a
dropping :: Int -> IndexedTraversal' i s a          -> IndexedTraversal' i s a
dropping :: Int -> IndexedLens' i s a               -> IndexedTraversal' i s a
dropping :: Int -> IndexedGetter i s a              -> IndexedFold i s a
dropping :: Int -> IndexedFold i s a                -> IndexedFold i s a
valuefailing
  1. :: (Conjoined p, Applicative f)
  2. => Traversing p f s t a b
  3. -> Over p f s t a b
  4. -> Over p f s t a b
#

Try the first Traversal (or Fold), falling back on the second Traversal (or Fold) if it returns no entries.

This is only a valid Traversal if the second Traversal is disjoint from the result of the first or returns exactly the same results. These conditions are trivially met when given a Lens, Iso, Getter, Prism or "affine" Traversal -- one that has 0 or 1 target.

Mutatis mutandis for Fold.

Example1 expression
[0,1,2,3] ^? failing (ix 1) (ix 2)Just 1
Example1 expression
[0,1,2,3] ^? failing (ix 42) (ix 2)Just 2
failing :: Traversal s t a b -> Traversal s t a b -> Traversal s t a b
failing :: Prism s t a b     -> Prism s t a b     -> Traversal s t a b
failing :: Fold s a          -> Fold s a          -> Fold s a

These cases are also supported, trivially, but are boring, because the left hand side always succeeds.

failing :: Lens s t a b      -> Traversal s t a b -> Traversal s t a b
failing :: Iso s t a b       -> Traversal s t a b -> Traversal s t a b
failing :: Equality s t a b  -> Traversal s t a b -> Traversal s t a b
failing :: Getter s a        -> Fold s a          -> Fold s a

If both of the inputs are indexed, the result is also indexed, so you can apply this to a pair of indexed traversals or indexed folds, obtaining an indexed traversal or indexed fold.

failing :: IndexedTraversal i s t a b -> IndexedTraversal i s t a b -> IndexedTraversal i s t a b
failing :: IndexedFold i s a          -> IndexedFold i s a          -> IndexedFold i s a

These cases are also supported, trivially, but are boring, because the left hand side always succeeds.

failing :: IndexedLens i s t a b      -> IndexedTraversal i s t a b -> IndexedTraversal i s t a b
failing :: IndexedGetter i s a        -> IndexedGetter i s a        -> IndexedFold i s a
valuedeepOf
  1. :: (Conjoined p, Applicative f)
  2. => LensLike f s t s t
  3. -> Traversing p f s t a b
  4. -> Over p f s t a b
#

Try the second traversal. If it returns no entries, try again with all entries from the first traversal, recursively.

deepOf :: Fold s s          -> Fold s a                   -> Fold s a
deepOf :: Traversal' s s    -> Traversal' s a             -> Traversal' s a
deepOf :: Traversal s t s t -> Traversal s t a b          -> Traversal s t a b
deepOf :: Fold s s          -> IndexedFold i s a          -> IndexedFold i s a
deepOf :: Traversal s t s t -> IndexedTraversal i s t a b -> IndexedTraversal i s t a b

Indexed Traversals

0 declarations

Common

valueelementOf
  1. :: Applicative f
  2. => LensLike (Indexing f) s t a a
  3. -> Int
  4. -> IndexedLensLike Int f s t a a
#

Traverse the nth elementOf a Traversal, Lens or Iso if it exists.

Example1 expression
[[1],[3,4]] & elementOf (traverse.traverse) 1 .~ 5[[1],[5,4]]
Example1 expression
[[1],[3,4]] ^? elementOf (folded.folded) 1Just 3
Example1 expression
timingOut $ ['a'..] ^?! elementOf folded 5'f'
Example1 expression
timingOut $ take 10 $ elementOf traverse 3 .~ 16 $ [0..][0,1,2,16,4,5,6,7,8,9]
elementOf :: Traversal' s a -> Int -> IndexedTraversal' Int s a
elementOf :: Fold s a       -> Int -> IndexedFold Int s a

Combinators

valueitraverseOf
  1. :: Indexed i a (f b) -> s -> f t
  2. -> i -> a -> f b
  3. -> s
  4. -> f t
#

Traversal with an index.

NB: When you don't need access to the index then you can just apply your IndexedTraversal directly as a function!

itraverseOf ≡ Control.Lens.Indexed.withIndex
traverseOf l = itraverseOf l . const = id
itraverseOf :: Functor f     => IndexedLens i s t a b       -> (i -> a -> f b) -> s -> f t
itraverseOf :: Applicative f => IndexedTraversal i s t a b  -> (i -> a -> f b) -> s -> f t
itraverseOf :: Apply f       => IndexedTraversal1 i s t a b -> (i -> a -> f b) -> s -> f t
valueimapMOf
  1. :: Over (Indexed i) (WrappedMonad m) s t a b
  2. -> i -> a -> m b
  3. -> s
  4. -> m t
#

Map each element of a structure targeted by a Lens to a monadic action, evaluate these actions from left to right, and collect the results, with access its position.

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

mapMOf l ≡ imapMOf l . const
imapMOf :: Monad m => IndexedLens       i s t a b -> (i -> a -> m b) -> s -> m t
imapMOf :: Monad m => IndexedTraversal  i s t a b -> (i -> a -> m b) -> s -> m t
imapMOf :: Bind  m => IndexedTraversal1 i s t a b -> (i -> a -> m b) -> s -> m t
valueiforMOf
  1. :: Indexed i a (WrappedMonad m b) -> s -> WrappedMonad m t
  2. -> s
  3. -> i -> a -> m b
  4. -> m t
#

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

forMOf l a ≡ iforMOf l a . const
iforMOf ≡ flip . imapMOf
iforMOf :: Monad m => IndexedLens i s t a b      -> s -> (i -> a -> m b) -> m t
iforMOf :: Monad m => IndexedTraversal i s t a b -> s -> (i -> a -> m b) -> m t
valueimapAccumROf
  1. :: Over (Indexed i) (Backwards (State acc)) s t a b
  2. -> i -> acc -> a -> (acc, b)
  3. -> acc
  4. -> s
  5. -> (acc, t)
#

Generalizes Data.Traversable.mapAccumR to an arbitrary IndexedTraversal with access to the index.

imapAccumROf accumulates state from right to left.

mapAccumROf l ≡ imapAccumROf l . const
imapAccumROf :: IndexedLens i s t a b      -> (i -> acc -> a -> (acc, b)) -> acc -> s -> (acc, t)
imapAccumROf :: IndexedTraversal i s t a b -> (i -> acc -> a -> (acc, b)) -> acc -> s -> (acc, t)

Reflection

4 declarations

Implementation Details

6 declarations
newtypenewtype Bazaar (p :: Type -> Type -> Type) a b t
#

This is used to characterize a Control.Lens.Traversal.Traversal.

a.k.a. indexed Cartesian store comonad, indexed Kleene store comonad, or an indexed FunList.

http://twanvl.nl/blog/haskell/non-regular1

A Bazaar is like a Control.Lens.Traversal.Traversal that has already been applied to some structure.

Where a Context a b t holds an a and a function from b to t, a Bazaar a b t holds N as and a function from N bs to t, (where N might be infinite).

Mnemonically, a Bazaar holds many stores and you can easily add more.

This is a final encoding of Bazaar.

Constructors

Instances9Bizarre, Sellable, IndexedComonad, IndexedFunctor, Functor, Applicative, …
newtypenewtype Bazaar1 (p :: Type -> Type -> Type) a b t
#

This is used to characterize a Control.Lens.Traversal.Traversal.

a.k.a. indexed Cartesian store comonad, indexed Kleene store comonad, or an indexed FunList.

http://twanvl.nl/blog/haskell/non-regular1

A Bazaar1 is like a Control.Lens.Traversal.Traversal that has already been applied to some structure.

Where a Context a b t holds an a and a function from b to t, a Bazaar1 a b t holds N as and a function from N bs to t, (where N might be infinite).

Mnemonically, a Bazaar1 holds many stores and you can easily add more.

This is a final encoding of Bazaar1.

Constructors

Instances8Bizarre1, Sellable, IndexedComonad, IndexedFunctor, Functor, Comonad, …

Fusion

1 declaration
valueconfusing
  1. :: Applicative f
  2. => LensLike (Curried (Yoneda f) (Yoneda f)) s t a b
  3. -> LensLike f s t a b
#

Fuse a Traversal by reassociating all of the (<*>) operations to the left and fusing all of the fmap calls into one. This is particularly useful when constructing a Traversal using operations from GHC.Generics.

Given a pair of Traversals foo and bar,

confusing (foo.bar) = foo.bar

However, foo and bar are each going to use the Applicative they are given.

confusing exploits the Yoneda lemma to merge their separate uses of fmap into a single fmap. and it further exploits an interesting property of the right Kan lift (or Curried) to left associate all of the uses of (<*>) to make it possible to fuse together more fmaps.

This is particularly effective when the choice of functor f is unknown at compile time or when the Traversal foo.bar in the above description is recursive or complex enough to prevent inlining.

fusing is a version of this combinator suitable for fusing lenses.

confusing :: Traversal s t a b -> Traversal s t a b