Safe Haskell | None |
---|
- data Zipper st b = Zipper {}
- data Top a = Top
- data (st :> b) c = Snoc (st b) (c -> b)
- class Hist st a c where
- runHist :: st c -> c -> a
- zipper :: a -> Zipper Top a
- close :: Hist st a b => Zipper st b -> a
- move :: Monad m => LensM m b c -> Zipper st b -> m (Zipper (st :> b) c)
- moveP :: (b :-> c) -> Zipper st b -> Zipper (st :> b) c
- moveUp :: Zipper (st :> b) c -> Zipper st b
- focus :: Zipper st b :-> b
- setf :: Zipper st b -> b -> Zipper st b
- modf :: (b -> b) -> Zipper st b -> Zipper st b
Documentation
We provide a simple, heterogenous, fully type-checked, generic zipper implementation. This flavor of zipper doesn't use "left" and "right" for navigation, and instead relies on lenses to indicate a child type to "move to".
Zipper type
Our zipper type, parameterized by a focus
and "history stack",
supporting completely type-checked zipper operations.
Zipper history
These three types make up the heterogenous history stack, and the programmer
should never need to use them directly. They come together with Zipper
to
form types that look like, e.g.
-- a zipper on a Tree, with focus on a leaf "a" of a 2nd level subtree z :: Zipper (Top :> Tree a :> Tree a) a
This zipper works conceptually like the "breacrumbs" navigation UI design pattern, and the types reflect this visually.
Nevertheless user-provided type annotations should almost never be necessary, so these will probably never appear in your code.
Zipper operations
close :: Hist st a b => Zipper st b -> aSource
exit the zipper, rebuilding the structure a
:
close (Zipper st b) = runHist st b
Motions
moveP :: (b :-> c) -> Zipper st b -> Zipper (st :> b) cSource
navigate to a child element indicated by the passed pure lens
moveP l = runIdentity . move l
moveUp :: Zipper (st :> b) c -> Zipper st bSource
navigate up a level in a zipper not already at Top
moveUp (Zipper (Snoc st cont) c) = Zipper st $ cont c
Focus
In addition to these, viewf
can be used to view the focus.