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

A Traversal lifts an effectful operation on elements to act on structures containing those elements.

That is, given a function op :: A -> F B where F is Applicative, a Traversal S T A B can produce a function S -> F T that applies op to all the As contained in the S.

This can be seen as a generalisation of traverse, where the type S does not need to be a type constructor with A as the last parameter.

A Lens is a Traversal that acts on a single value.

A close relative is the AffineTraversal, which is a Traversal that acts on at most one value.

  • 5 types
  • 19 values

Formation

2 declarations

Introduction

1 declaration

Elimination

1 declaration

Computation

0 declarations

Well-formedness

0 declarations

Additional introduction forms

2 declarations
valueboth :: Bitraversable r => Traversal (r a a) (r b b) a b
#

Traverse both parts of a Bitraversable container with matching types.

Note: for traversing a pair or an Either it's better to use each and chosen respectively to reduce potential for bugs due to too much polymorphism.

Example1 expression
(1,2) & both %~ (*10)(10,20)
Example1 expression
over both length ("hello","world")(5,5)
Example1 expression
foldOf both ("hello","world")"helloworld"

Additional elimination forms

11 declarations
valuerewriteMOf
  1. :: (Is k A_Traversal, Monad m)
  2. => Optic k is a b a b
  3. -> b -> m (Maybe a)
  4. -> a
  5. -> m b
#

Rewrite by applying a monadic rule everywhere you recursing with a user-specified Traversal.

Ensures that the rule cannot be applied anywhere in the result.

valuefailover
  1. :: Is k A_Traversal
  2. => Optic k is s t a b
  3. -> a -> b
  4. -> s
  5. -> Maybe t
#

Try to map a function over this Traversal, returning Nothing if the traversal has no targets.

Example1 expression
failover (element 3) (*2) [1,2]Nothing
Example1 expression
failover _Left (*2) (Right 4)Nothing
Example1 expression
failover _Right (*2) (Right 4)Just (Right 8)

Combinators

3 declarations
valuepartsOf :: Is k A_Traversal => Optic k is s t a a -> Lens s t [a] [a]
#

partsOf turns a Traversal into a Lens.

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.

Monoid structure

1 declaration

Traversal admits a (partial) monoid structure where adjoin combines non-overlapping traversals, and the identity element is ignored (which traverses no elements).

If you merely need a Fold, you can use traversals as folds and combine them with one of the monoid structures on folds (see Optics.Fold#monoids). In particular, summing can be used to concatenate results from two traversals, and failing will returns results from the second traversal only if the first returns no results.

There is no Semigroup or Monoid instance for Traversal, because there is not a unique choice of monoid to use that works for all optics, and the (<>) operator could not be used to combine optics of different kinds.

valueadjoin
  1. :: (Is k A_Traversal, Is l A_Traversal)
  2. => Optic' k is s a
  3. -> Optic' l js s a
  4. -> Traversal' s a
#

Combine two disjoint traversals into one.

Example1 expression
over (_1 % _Just `adjoin` _2 % _Right) not (Just True, Right False)(Just False,Right True)

Note: if the argument traversals are not disjoint, the result will not respect the Traversal 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
view (partsOf (each `adjoin` _1)) ('x','y')"xyx"set (partsOf (each `adjoin` _1)) "abc" ('x','y')('c','b')

For the Fold version see summing.

Subtyping

1 declaration
datadata A_Traversal
#

Tag for a traversal.

Instances28Is, JoinKinds, IxOptic, ToReadOnly, ReadOnlyOptic, …

van Laarhoven encoding

2 declarations

The van Laarhoven representation of a Traversal directly expresses how it lifts an effectful operation A -> F B on elements to act on structures S -> F T. Thus traverseOf converts a Traversal to a TraversalVL.

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

Type synonym for a type-modifying van Laarhoven traversal.