``Scrap Your Zippers: A Generic Zipper for Heterogeneous Types. Michael D. Adams. WGP '10: Proceedings of the 2010 ACM SIGPLAN workshop on Generic programming, 2010.''
See http://www.cs.indiana.edu/~adamsmd/papers/scrap_your_zippers/
- data Zipper root
- toZipper :: Data a => a -> Zipper a
- fromZipper :: Zipper a -> a
- left :: Zipper a -> Maybe (Zipper a)
- right :: Zipper a -> Maybe (Zipper a)
- down :: Zipper a -> Maybe (Zipper a)
- down' :: Zipper a -> Maybe (Zipper a)
- up :: Zipper a -> Maybe (Zipper a)
- query :: GenericQ b -> Zipper a -> b
- trans :: GenericT -> Zipper a -> Zipper a
- transM :: Monad m => GenericM m -> Zipper a -> m (Zipper a)
- getHole :: Typeable b => Zipper a -> Maybe b
- setHole :: Typeable a => a -> Zipper b -> Zipper b
- setHole' :: Typeable a => a -> Zipper b -> Maybe (Zipper b)
- moveQ :: Move a -> b -> (Zipper a -> b) -> Zipper a -> b
- leftQ :: b -> (Zipper a -> b) -> Zipper a -> b
- rightQ :: b -> (Zipper a -> b) -> Zipper a -> b
- downQ :: b -> (Zipper a -> b) -> Zipper a -> b
- upQ :: b -> (Zipper a -> b) -> Zipper a -> b
- moveT :: Move a -> Move a -> Zipper a -> (Zipper a -> Zipper a) -> Zipper a -> Zipper a
- leftT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper a
- rightT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper a
- downT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper a
- upT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper a
- moveM :: Monad m => Move a -> Move a -> m (Zipper a) -> (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)
- rightM :: Monad m => m (Zipper a) -> (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)
- downM :: Monad m => m (Zipper a) -> (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)
- upM :: Monad m => m (Zipper a) -> (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)
- leftmost :: Zipper a -> Zipper a
- rightmost :: Zipper a -> Zipper a
- zmapQ :: GenericQ b -> Zipper a -> [b]
- zmapT :: GenericT -> Zipper a -> Zipper a
- zmapM :: Monad m => GenericM m -> Zipper a -> m (Zipper a)
- zmapMp :: MonadPlus m => GenericM m -> Zipper a -> m (Zipper a)
- zeverywhere :: GenericT -> Zipper a -> Zipper a
- zeverywhere' :: GenericT -> Zipper a -> Zipper a
- zsomewhere :: MonadPlus m => GenericM m -> Zipper a -> m (Zipper a)
- zreduce :: GenericM Maybe -> Zipper a -> Zipper a
Core types
Core interface
Injection and projection
toZipper :: Data a => a -> Zipper aSource
Create a zipper. The focus starts at the root of the object.
fromZipper :: Zipper a -> aSource
Move up a zipper to the root and return the root object.
Basic movement
left :: Zipper a -> Maybe (Zipper a)Source
Move left. Returns Nothing
iff already at leftmost sibling.
right :: Zipper a -> Maybe (Zipper a)Source
Move right. Returns Nothing
iff already at rightmost sibling.
down :: Zipper a -> Maybe (Zipper a)Source
Move down. Moves to rightmost immediate child. Returns Nothing
iff at a leaf and thus no children exist.
down' :: Zipper a -> Maybe (Zipper a)Source
Move down. Move to the leftmost immediate child. Returns Nothing
iff at a leaf and thus no children exist.
up :: Zipper a -> Maybe (Zipper a)Source
Move up. Returns Nothing
iff already at root and thus no parent exists.
Basic hole manipulation
transM :: Monad m => GenericM m -> Zipper a -> m (Zipper a)Source
Apply a generic monadic transformation to the hole
Convenience hole manipulation interface
getHole :: Typeable b => Zipper a -> Maybe bSource
Get the value in the hole. Returns Nothing
iff a
is not the type of the value in the hole.
setHole :: Typeable a => a -> Zipper b -> Zipper bSource
Set the value in the hole. Does nothing iff a
is not the type of the value in the hole.
setHole' :: Typeable a => a -> Zipper b -> Maybe (Zipper b)Source
Set the value in the hole. Returns Nothing
iff a
is not the type of the value in the hole.
Generic zipper traversals
Traversal helpers
Query
:: Move a | Move operation |
-> b | Default if can't move |
-> (Zipper a -> b) | Query if can move |
-> Zipper a | Zipper |
-> b |
Apply a generic query using the specified movement operation.
Apply a generic query to the left sibling if one exists.
Apply a generic query to the right sibling if one exists.
Apply a generic query to the parent if it exists.
Apply a generic query to the rightmost child if one exists.
Transform
:: Move a | Move to |
-> Move a | Move back |
-> Zipper a | Default if can't move |
-> (Zipper a -> Zipper a) | Transformer if can move |
-> Zipper a | Zipper |
-> Zipper a |
Apply a generic transformer using the specified movement operations.
leftT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper aSource
Apply a generic transformer to the left sibling if one exists. Otherwise, leaves the zipper unchanged.
rightT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper aSource
Apply a generic transformer to the right sibling if one exists. Otherwise, leaves the zipper unchanged.
downT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper aSource
Apply a generic transformer to the rightmost child if one exists. Otherwise, leaves the zipper unchanged.
upT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper aSource
Apply a generic transformer to the parent if it exists. Otherwise, leaves the zipper unchanged.
Monadic Transform
:: Monad m | |
=> Move a | Move to |
-> Move a | Move back |
-> m (Zipper a) | Default if can't move |
-> (Zipper a -> m (Zipper a)) | Monadic transformer if can move |
-> Zipper a | Zipper |
-> m (Zipper a) |
Apply a generic monadic transformer using the specified movement operations.
:: Monad m | |
=> m (Zipper a) | Value to return if no right sibling exists. |
-> (Zipper a -> m (Zipper a)) | |
-> Zipper a | |
-> m (Zipper a) |
Apply a generic monadic transformer to the right sibling if one exists.
:: Monad m | |
=> m (Zipper a) | Value to return if no children exist. |
-> (Zipper a -> m (Zipper a)) | |
-> Zipper a | |
-> m (Zipper a) |
Apply a generic monadic transformer to the rightmost child if one exists.
:: Monad m | |
=> m (Zipper a) | Value to return if parent does not exist. |
-> (Zipper a -> m (Zipper a)) | |
-> Zipper a | |
-> m (Zipper a) |
Apply a generic monadic transformer to the parent if it exists.
Movement
Map traversals
zmapT :: GenericT -> Zipper a -> Zipper aSource
Apply a generic transformation to the immediate children.
zmapM :: Monad m => GenericM m -> Zipper a -> m (Zipper a)Source
Apply a generic monadic transformation to the immediate children.
zmapMp :: MonadPlus m => GenericM m -> Zipper a -> m (Zipper a)Source
Apply a generic monadic transformation to at least one child that does not fail.
Tree traversals
zeverywhere :: GenericT -> Zipper a -> Zipper aSource
Apply a generic transformation everywhere in a bottom-up manner.
zeverywhere' :: GenericT -> Zipper a -> Zipper aSource
Apply a generic transformation everywhere in a top-down manner.
zsomewhere :: MonadPlus m => GenericM m -> Zipper a -> m (Zipper a)Source
Apply a generic monadic transformation once at the topmost leftmost successful location.
zreduce :: GenericM Maybe -> Zipper a -> Zipper aSource
Repeatedly apply a monadic Maybe
generic transformation at the
top-most, left-most position that the transformation returns
Just
. Behaves like iteratively applying zsomewhere
but is
more efficient because it re-evaluates the transformation
at only the parents of the last successful application.