The pez package
PEZ is a generic zipper library. It uses lenses from the fclabels package to reference a location to move to in the zipper. The zipper is restricted to types in the Typeable class, allowing the user to move up through complex data structures such as mutually-recursive types.
Both the Typeable class and fclabels lenses can be derived in GHC, making it easy for the programmer to use a zipper with a minimum of boilerplate.
First import the library, which brings in the Typeable and fclabels modules. You will also want to enable a few extensions:
-- Put these in a LANGUAGE pragma: -- TemplateHaskell, DeriveDataTypeable, TypeOperators module Main where import Data.Typeable.Zipper
Create a datatype, deriving an instance of the Typeable class, and generate a lens using functions from fclabels:
data Tree a = Node _leftNode :: Tree a , _val :: a , _rightNode :: Tree a | Nil deriving (Typeable,Show) $(mkLabelsNoTypes [''Tree])
Now we can go crazy using Tree in a Zipper:
treeBCD = Node (Node Nil 'b' Nil) 'c' (Node Nil 'd' Nil) descendLeft :: Zipper1 (Tree a) -> Zipper1 (Tree a) descendLeft z = case (viewf z) of Nil -> z _ -> descendLeft $ moveTo leftNode z insertLeftmost :: a -> Tree a -> Tree a insertLeftmost x = close . setL focus x . descendLeft . zipper treeABCD = insertLeftmost 'a' treeBCD
Because of the flexibility of fclabels, this zipper library can be used to express moving about in reversible computations simply by defining such a lens, for instance:
stringRep :: (Show b, Read b) => b :-> String stringRep = lens show (const . read)
Please send any feature requests or bug reports along.
|Versions||0.0.1, 0.0.2, 0.0.3, 0.0.4, 0.1.0|
|Dependencies||base (4.*), fclabels (≥0.11.1.1 & <0.12), thrist (0.2.*)|
|Copyright||Brandon Simmons, 2011|
|Upload date||Thu Apr 28 00:28:30 UTC 2011|