zipper package:zippers -is:package

Construct a Zipper that can explore anything, and start it at the Top.
This module provides a Zipper with fairly strong type checking guarantees. The code here is inspired by Brandon Simmons' zippo package, but uses a different approach to represent the Zipper that makes the whole thing look like his breadcrumb trail, and can move side-to-side through traversals. Some examples types: Since individual levels of a Zipper are managed by an arbitrary IndexedTraversal, you can move left and right through the IndexedTraversal selecting neighboring elements.
>>> zipper ("hello","world") & downward _1 & fromWithin traverse & focus .~ 'J' & rightmost & focus .~ 'y' & rezip
("Jelly","world")
This is particularly powerful when compiled with plate, uniplate or biplate for walking down into self-similar children in syntax trees and other structures. Given keys in ascending order you can jump directly to a given key with moveTo. When used with traversals for balanced tree-like structures such as an IntMap or Map, searching for a key with moveTo can be done in logarithmic time.
This is the type of a Zipper. It visually resembles a "breadcrumb trail" as used in website navigation. Each breadcrumb in the trail represents a level you can move up to. This type operator associates to the left, so you can use a type like
Top :>> (String,Double) :>> String :>> Char
to represent a Zipper from (String,Double) down to Char that has an intermediate crumb for the String containing the Char. You can construct a Zipper into *any* data structure with zipper. You can repackage up the contents of a Zipper with rezip.
>>> rezip $ zipper 42
42
The combinators in this module provide lot of things you can do to the Zipper while you have it open. Note that a value of type h :> s :> a doesn't actually contain a value of type h :> s -- as we descend into a level, the previous level is unpacked and stored in Coil form. Only one value of type _ :> _ exists at any particular time for any particular Zipper.