zippo-0.3: A simple lens-based, generic, heterogenous, type-checked zipper library

Safe HaskellNone





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

data Zipper st b Source

Our zipper type, parameterized by a focus and "history stack", supporting completely type-checked zipper operations.




hist :: st b
viewf :: b

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.

data Top a Source




~ * a b => Hist Top a b 

data (st :> b) c Source


Snoc (st b) (c -> b) 


Hist st a b => Hist (:> st b) a c 

class Hist st a c whereSource


runHist :: st c -> c -> aSource


~ * a b => Hist Top a b 
Hist st a b => Hist (:> st b) a c 

Zipper operations

zipper :: a -> Zipper Top aSource

"enter" a data type. Move the focus with move and moveUp. Exit the zipper with close.

 zipper = Zipper Top

close :: Hist st a b => Zipper st b -> aSource

exit the zipper, rebuilding the structure a:

 close (Zipper st b) = runHist st b


move :: Monad m => LensM m b c -> Zipper st b -> m (Zipper (st :> b) c)Source

navigate to a child element indicated by the passed lens, returning the new Zipper in the monad m. This will be Maybe when the standard (:~>) Lens is used. For pure lenses, use moveP.

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


In addition to these, viewf can be used to view the focus.

focus :: Zipper st b :-> bSource

A lens on the focus of the zipper.

setf :: Zipper st b -> b -> Zipper st bSource

Set the zipper focus

 setf = set focus

modf :: (b -> b) -> Zipper st b -> Zipper st bSource

Modify the zipper focus

 modf = modify focus