HORIZON HASKELLDocslts/ghc-10.0.x77a86622026-10-31Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 77a8662 · 2026-10-31

Moduleoptics-core-0.4.2Haskell2010

Optics.AffineTraversal

An AffineTraversal is a Traversal that applies to at most one element.

These arise most frequently as the composition of a Lens with a Prism.

Contents
  1. Formation
  2. Introduction
  3. Elimination
  4. Computation
  5. Additional introduction forms
  6. Additional elimination forms
  7. Monoid structure
  8. Subtyping
  9. van Laarhoven encoding
Synopsis
  • Packageoptics-core-0.4.2
  • Exports12
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceAffineTraversal.hs

Formation

Introduction

Elimination

An AffineTraversal is in particular an AffineFold and a Setter, therefore you can specialise types to obtain:

preview :: AffineTraversal s t a b -> s -> Maybe a
over    :: AffineTraversal s t a b -> (a -> b) -> s -> t
set     :: AffineTraversal s t a b ->       b  -> s -> t

Computation

matching (atraversal f g) ≡ f
isRight (f s)  =>  set (atraversal f g) b s ≡ g s b

Additional introduction forms

See _head, _tail, _init and _last for AffineTraversals for container types.

valueunsafeFiltered :: (a -> Bool) -> AffineTraversal' a a

Filter result(s) of a traversal that don't satisfy a predicate.

Note: This is not a legal Traversal, unless you are very careful not to invalidate the predicate on the target.

As a counter example, consider that given evens = unsafeFiltered even the second Traversal law is violated:

over evens succ . Optics.over evens succ /= over evens (succ . succ)

So, in order for this to qualify as a legal Traversal you can only use it for actions that preserve the result of the predicate!

For a safe variant see indices (or filtered for read-only optics).

Additional elimination forms

Monoid structure

AffineTraversal admits a monoid structure where adisjoin returns the result from the second affine traversal only if the first does not return a result. The identity element is ignored (which traverses no elements).

Subtyping

Tag for an affine traversal.

Instances31Is, ArrowOptic, JoinKinds, IxOptic, ToReadOnly, GenericOptic, …

van Laarhoven encoding

typetype AffineTraversalVL s t a b = forall (f :: Type -> Type). Functor f => (forall r. r -> f r) -> (a -> f b) -> s -> f t

Type synonym for a type-modifying van Laarhoven 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).

A TraversalVL has Applicative available and hence can combine the effects arising from multiple elements using <*>. In contrast, an AffineTraversalVL has no way to combine effects from multiple elements, so it must act on at most one element. (It can act on none at all thanks to the availability of point.)

valueatraversalVL :: AffineTraversalVL s t a b -> AffineTraversal s t a b

Build an affine traversal from the van Laarhoven representation.

Example:

Example1 expression
:{azSnd = atraversalVL $ \point f ab@(a, b) ->  if a >= 'a' && a <= 'z'  then (a, ) <$> f b  else point ab:}
Example1 expression
preview azSnd ('a', "Hi")Just "Hi"
Example1 expression
preview azSnd ('@', "Hi")Nothing
Example1 expression
over azSnd (++ "!!!") ('f', "Hi")('f',"Hi!!!")
Example1 expression
set azSnd "Bye" ('Y', "Hi")('Y',"Hi")