-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Scrap Your Zippers
--   
--   This package contains the generic zipper system described in the Scrap
--   Your Zippers paper (see
--   <a>http://www.cs.indiana.edu/~adamsmd/papers/scrap_your_zippers/</a>).
--   It defines the <tt>Zipper</tt> type permitting zipper traversals over
--   arbitrary instances of <tt>Data</tt>.
@package syz
@version 0.2.0.0


-- | ``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
--   <a>http://www.cs.indiana.edu/~adamsmd/papers/scrap_your_zippers/</a>
module Data.Generics.Zipper

-- | A generic zipper with a root object of type <tt>root</tt>.
data Zipper root

-- | Create a zipper. The focus starts at the root of the object.
toZipper :: (Data a) => a -> Zipper a

-- | Move up a zipper to the root and return the root object.
fromZipper :: Zipper a -> a

-- | Move left. Returns <a>Nothing</a> iff already at leftmost sibling.
left :: Zipper a -> Maybe (Zipper a)

-- | Move right. Returns <a>Nothing</a> iff already at rightmost sibling.
right :: Zipper a -> Maybe (Zipper a)

-- | Move down. Moves to rightmost immediate child. Returns <a>Nothing</a>
--   iff at a leaf and thus no children exist.
down :: Zipper a -> Maybe (Zipper a)

-- | Move down. Move to the leftmost immediate child. Returns
--   <a>Nothing</a> iff at a leaf and thus no children exist.
down' :: Zipper a -> Maybe (Zipper a)

-- | Move up. Returns <a>Nothing</a> iff already at root and thus no parent
--   exists.
up :: Zipper a -> Maybe (Zipper a)

-- | Apply a generic query to the hole.
query :: GenericQ b -> Zipper a -> b

-- | Apply a generic transformation to the hole.
trans :: GenericT -> Zipper a -> Zipper a

-- | Apply a generic monadic transformation to the hole
transM :: (Monad m) => GenericM m -> Zipper a -> m (Zipper a)

-- | Get the value in the hole. Returns <a>Nothing</a> iff <tt>a</tt> is
--   not the type of the value in the hole.
getHole :: (Typeable b) => Zipper a -> Maybe b

-- | Set the value in the hole. Does nothing iff <tt>a</tt> is not the type
--   of the value in the hole.
setHole :: (Typeable a) => a -> Zipper b -> Zipper b

-- | Set the value in the hole. Returns <a>Nothing</a> iff <tt>a</tt> is
--   not the type of the value in the hole.
setHole' :: (Typeable a) => a -> Zipper b -> Maybe (Zipper b)

-- | Apply a generic query using the specified movement operation.
moveQ :: Move a -> b -> (Zipper a -> b) -> Zipper a -> b

-- | Apply a generic query to the left sibling if one exists.
leftQ :: b -> (Zipper a -> b) -> Zipper a -> b

-- | Apply a generic query to the right sibling if one exists.
rightQ :: b -> (Zipper a -> b) -> Zipper a -> b

-- | Apply a generic query to the parent if it exists.
downQ :: b -> (Zipper a -> b) -> Zipper a -> b

-- | Apply a generic query to the rightmost child if one exists.
upQ :: b -> (Zipper a -> b) -> Zipper a -> b

-- | Apply a generic transformer using the specified movement operations.
moveT :: Move a -> Move a -> Zipper a -> (Zipper a -> Zipper a) -> Zipper a -> Zipper a

-- | Apply a generic transformer to the left sibling if one exists.
--   Otherwise, leaves the zipper unchanged.
leftT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper a

-- | Apply a generic transformer to the right sibling if one exists.
--   Otherwise, leaves the zipper unchanged.
rightT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper a

-- | Apply a generic transformer to the rightmost child if one exists.
--   Otherwise, leaves the zipper unchanged.
downT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper a

-- | Apply a generic transformer to the parent if it exists. Otherwise,
--   leaves the zipper unchanged.
upT :: (Zipper a -> Zipper a) -> Zipper a -> Zipper a

-- | Apply a generic monadic transformer using the specified movement
--   operations.
moveM :: (Monad m) => Move a -> Move a -> m (Zipper a) -> (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)

-- | Apply a generic monadic transformer to the right sibling if one
--   exists.
rightM :: (Monad m) => m (Zipper a) -> (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)

-- | Apply a generic monadic transformer to the rightmost child if one
--   exists.
downM :: (Monad m) => m (Zipper a) -> (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)

-- | Apply a generic monadic transformer to the parent if it exists.
upM :: (Monad m) => m (Zipper a) -> (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)

-- | Move to the leftmost sibling.
leftmost :: Zipper a -> Zipper a

-- | Move to the rightmost sibling.
rightmost :: Zipper a -> Zipper a

-- | Apply a generic query to the immediate children.
zmapQ :: GenericQ b -> Zipper a -> [b]

-- | Apply a generic transformation to the immediate children.
zmapT :: GenericT -> Zipper a -> Zipper a

-- | Apply a generic monadic transformation to the immediate children.
zmapM :: (Monad m) => GenericM m -> Zipper a -> m (Zipper a)

-- | Apply a generic monadic transformation to at least one child that does
--   not fail.
zmapMp :: (MonadPlus m) => GenericM m -> Zipper a -> m (Zipper a)

-- | Apply a generic transformation everywhere in a bottom-up manner.
zeverywhere :: GenericT -> Zipper a -> Zipper a

-- | Apply a generic transformation everywhere in a top-down manner.
zeverywhere' :: GenericT -> Zipper a -> Zipper a

-- | Apply a generic monadic transformation once at the topmost leftmost
--   successful location.
zsomewhere :: (MonadPlus m) => GenericM m -> Zipper a -> m (Zipper a)

-- | Repeatedly apply a monadic <a>Maybe</a> generic transformation at the
--   top-most, left-most position that the transformation returns
--   <a>Just</a>. Behaves like iteratively applying <a>zsomewhere</a> but
--   is more efficient because it re-evaluates the transformation at only
--   the parents of the last successful application.
zreduce :: GenericM Maybe -> Zipper a -> Zipper a
