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

Modulelens-5.3.5Haskell2010

Control.Lens.Level

This module provides combinators for breadth-first searching within arbitrary traversals.

  • 1 type
  • 2 values
  • Packagelens-5.3.5
  • Exports3
  • LanguageHaskell2010
  • LicenceBSD-2-Clause
  • SourceLevel.hs
datadata Level i a
#

This data type represents a path-compressed copy of one level of a source data structure. We can safely use path-compression because we know the depth of the tree.

Path compression is performed by viewing a Level as a PATRICIA trie of the paths into the structure to leaves at a given depth, similar in many ways to a Data.IntMap.IntMap, but unlike a regular PATRICIA trie we do not need to store the mask bits merely the depth of the fork.

One invariant of this structure is that underneath a Two node you will not find any Zero nodes, so Zero can only occur at the root.

Instances10FoldableWithIndex, FunctorWithIndex, TraversableWithIndex, Functor, Foldable, Traversable, …
valuelevels
  1. :: Applicative f
  2. => Traversing (->) f s t a b
  3. -> IndexedLensLike Int f s t (Level () a) (Level () b)
#

This provides a breadth-first Traversal or Fold of the individual levels of any other Traversal or Fold via iterative deepening depth-first search. The levels are returned to you in a compressed format.

This can permit us to extract the levels directly:

Example1 expression
["hello","world"]^..levels (traverse.traverse)[Zero,Zero,One () 'h',Two 0 (One () 'e') (One () 'w'),Two 0 (One () 'l') (One () 'o'),Two 0 (One () 'l') (One () 'r'),Two 0 (One () 'o') (One () 'l'),One () 'd']

But we can also traverse them in turn:

Example1 expression
["hello","world"]^..levels (traverse.traverse).traverse"hewlolrold"

We can use this to traverse to a fixed depth in the tree of (<*>) used in the Traversal:

Example1 expression
["hello","world"] & taking 4 (levels (traverse.traverse)).traverse %~ toUpper["HEllo","World"]

Or we can use it to traverse the first n elements in found in that Traversal regardless of the depth at which they were found.

Example1 expression
["hello","world"] & taking 4 (levels (traverse.traverse).traverse) %~ toUpper["HELlo","World"]

The resulting Traversal of the levels which is indexed by the depth of each Level.

Example1 expression
["dog","cat"]^@..levels (traverse.traverse) <. traverse[(2,'d'),(3,'o'),(3,'c'),(4,'g'),(4,'a'),(5,'t')]
levels :: Traversal s t a b      -> IndexedTraversal Int s t (Level () a) (Level () b)
levels :: Fold s a               -> IndexedFold Int s (Level () a)

Note: Internally this is implemented by using an illegal Applicative, as it extracts information in an order that violates the Applicative laws.

valueilevels
  1. :: Applicative f
  2. => Traversing (Indexed i) f s t a b
  3. -> IndexedLensLike Int f s t (Level i a) (Level j b)
#

This provides a breadth-first Traversal or Fold of the individual levels of any other Traversal or Fold via iterative deepening depth-first search. The levels are returned to you in a compressed format.

This is similar to levels, but retains the index of the original IndexedTraversal, so you can access it when traversing the levels later on.

Example1 expression
["dog","cat"]^@..ilevels (traversed<.>traversed).itraversed[((0,0),'d'),((0,1),'o'),((1,0),'c'),((0,2),'g'),((1,1),'a'),((1,2),'t')]

The resulting Traversal of the levels which is indexed by the depth of each Level.

Example1 expression
["dog","cat"]^@..ilevels (traversed<.>traversed)<.>itraversed[((2,(0,0)),'d'),((3,(0,1)),'o'),((3,(1,0)),'c'),((4,(0,2)),'g'),((4,(1,1)),'a'),((5,(1,2)),'t')]
ilevels :: IndexedTraversal i s t a b      -> IndexedTraversal Int s t (Level i a) (Level i b)
ilevels :: IndexedFold i s a               -> IndexedFold Int s (Level i a)

Note: Internally this is implemented by using an illegal Applicative, as it extracts information in an order that violates the Applicative laws.