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


-- | Generic applicative traversals
--   
--   This is a generic programming library in the spirit of "Scrap your
--   boilerplate with class", but with several improvements — most notably,
--   it's based on the <tt>gtraverse</tt> function instead of
--   <tt>gfoldl</tt>. <tt>gtraverse</tt> is equivalent in power to
--   <tt>gfoldl</tt>, but lets you more easily write non-standard views of
--   the data type.
@package traverse-with-class
@version 1.0.0.0


-- | For the generated instances you'll typically need the following
--   extensions:
--   
--   <pre>
--   {-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances, ConstraintKinds, UndecidableInstances #-}
--   </pre>
module Data.Generics.Traversable.TH

-- | Example usage:
--   
--   <pre>
--   data MyType = MyType
--   
--   deriveGTraversable ''MyType
--   </pre>
--   
--   It tries to create the necessary instance constraints, but is not very
--   smart about it For tricky types, it may fail or produce an
--   overconstrained instance. In that case, write the instance declaration
--   yourself and use <a>gtraverseExpr</a> to derive the implementation:
--   
--   <pre>
--   data MyType a = MyType
--   
--   instance GTraversable (MyType a) where
--     gtraverse = $(gtraverseExpr ''MyType)
--   </pre>
deriveGTraversable :: Name -> Q [Dec]

-- | Return a lambda expression which implements <a>gtraverse</a> for the
--   given data type.
gtraverseExpr :: Name -> Q Exp


-- | All of the functions below work only on «interesting» subterms. It is
--   up to the instance writer to decide which subterms are interesting and
--   which subterms should count as immediate. This can also depend on the
--   context <tt>c</tt>.
--   
--   The context, denoted <tt>c</tt>, is a constraint (of kind <tt>* -&gt;
--   Constraint</tt>) that provides additional facilities to work with the
--   data. In most cases, the context cannot be inferred automatically. You
--   need to provide it using the <a>type application syntax</a>:
--   
--   <pre>
--   gmap @Show f x
--   everywhere @Typeable f x
--   </pre>
--   
--   etc.
--   
--   For more information, see:
--   
--   <ul>
--   <li><i>Scrap your boilerplate with class</i>
--   <a>https://www.microsoft.com/en-us/research/publication/scrap-your-boilerplate-with-class/</a></li>
--   <li><i>Generalizing generic fold</i>
--   <a>http://ro-che.info/articles/2013-03-11-generalizing-gfoldl</a></li>
--   </ul>
module Data.Generics.Traversable
class GTraversable (c :: * -> Constraint) a

-- | Applicative traversal over (a subset of) immediate subterms. This is a
--   generic version of <a>traverse</a>.
--   
--   The supplied function is applied only to the «interesting» subterms.
--   
--   Other subterms are lifted using <a>pure</a>, and the whole structure
--   is folded back using <a>&lt;*&gt;</a>.
--   
--   <a>gtraverse</a> has a default implementation <tt>const pure</tt>,
--   which works for types without interesting subterms (in particular,
--   atomic types).
gtraverse :: (GTraversable c a, (Applicative f)) => (forall d. c d => d -> f d) -> a -> f a

-- | Generic map over the immediate subterms
gmap :: forall c a. (GTraversable c a) => (forall d. (c d) => d -> d) -> a -> a

-- | Generic monadic map over the immediate subterms
gmapM :: forall c m a. (Monad m, GTraversable c a) => (forall d. (c d) => d -> m d) -> a -> m a

-- | Generic monoidal fold over the immediate subterms (cf. <a>foldMap</a>)
gfoldMap :: forall c r a. (Monoid r, GTraversable c a) => (forall d. (c d) => d -> r) -> a -> r

-- | Generic right fold over the immediate subterms
gfoldr :: forall c a r. (GTraversable c a) => (forall d. (c d) => d -> r -> r) -> r -> a -> r

-- | Generic strict left fold over the immediate subterms
gfoldl' :: forall c a r. (GTraversable c a) => (forall d. (c d) => r -> d -> r) -> r -> a -> r

-- | <a>Rec</a> enables "deep traversals".
--   
--   It is satisfied automatically when its superclass constraints are
--   satisfied — you are not supposed to declare new instances of this
--   class.
class (GTraversable (Rec c) a, c a) => Rec (c :: * -> Constraint) a

-- | Apply a transformation everywhere in bottom-up manner
everywhere :: forall c a. (Rec c a) => (forall d. (Rec c d) => d -> d) -> a -> a

-- | Apply a transformation everywhere in top-down manner
everywhere' :: forall c a. (Rec c a) => (forall d. (Rec c d) => d -> d) -> a -> a

-- | Monadic variation on everywhere
everywhereM :: forall c m a. (Monad m, Rec c a) => (forall d. (Rec c d) => d -> m d) -> a -> m a

-- | Strict left fold over all elements, top-down
everything :: forall c r a. (Rec c a) => (r -> r -> r) -> (forall d. (Rec c d) => d -> r) -> a -> r
instance (Data.Generics.Traversable.Core.GTraversable (Data.Generics.Traversable.Rec c) a, c a) => Data.Generics.Traversable.Rec c a


-- | Based on «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»
--   (<a>http://michaeldadams.org/papers/scrap_your_zippers/</a>).
--   
--   Compared to the original <tt>syz</tt> package, this implementation
--   (based on <a>GTraversable</a>) gives more flexibility as to where a
--   zipper may point to and what is considered as siblings.
--   
--   Specifically, a zipper may point to any element which <a>gtraverse</a>
--   applies its function to.
--   
--   <h2>Example</h2>
--   
--   <h3>syz</h3>
--   
--   Consider the classical example: lists. With syz, a list is interpreted
--   as a right-balanced tree.
--   
--   <pre>
--   &gt;&gt;&gt; let z = fromJust . down' $ toZipper ['a'..'d']
--   
--   &gt;&gt;&gt; getHole z :: Maybe Char
--   Just 'a'
--   </pre>
--   
--   The zipper <tt>z</tt> points to the first element of the list. Now
--   let's move to the right:
--   
--   <pre>
--   &gt;&gt;&gt; let z' = fromJust . right $ z
--   
--   &gt;&gt;&gt; getHole z' :: Maybe Char
--   Nothing
--   
--   &gt;&gt;&gt; getHole z' :: Maybe [Char]
--   Just "bcd"
--   </pre>
--   
--   Instead of pointing to the second element of the list, as one might
--   expect, the zipper <tt>z'</tt> points to the tail of the list. In
--   order to actually move to the second element, we need another
--   <a>down'</a>:
--   
--   <pre>
--   &gt;&gt;&gt; let z'' = fromJust . down' $ z'
--   
--   &gt;&gt;&gt; getHole z'' :: Maybe Char
--   Just 'b'
--   </pre>
--   
--   <h3>traverse-with-class</h3>
--   
--   <a>GTraversable</a>-based zippers behave more intuitively in this
--   regard, thanks to the uniform instance for lists.
--   
--   <pre>
--   &gt;&gt;&gt; let z = fromJust . down' $ toZipper ['a'..'d'] :: Zipper Typeable [Char]
--   
--   &gt;&gt;&gt; getHole z :: Maybe Char
--   Just 'a'
--   </pre>
--   
--   So far it's more or less the same as with syz. We needed to add a type
--   annotation for the zipper itself to clarify the context which should
--   be available at each hole (<a>Typeable</a> in this case). Now let's
--   see what's to the right of us:
--   
--   <pre>
--   &gt;&gt;&gt; let z' = fromJust . right $ z
--   
--   &gt;&gt;&gt; getHole z' :: Maybe Char
--   Just 'b'
--   </pre>
--   
--   That is, we jumped right to the second element of the list. Likewise,
--   
--   <pre>
--   &gt;&gt;&gt; let z'' = rightmost z
--   
--   &gt;&gt;&gt; getHole z'' :: Maybe Char
--   Just 'd'
--   </pre>
--   
--   So, unlike in <tt>syz</tt>, all of the list elements are siblings.
module Data.Generics.Traversable.Zipper

-- | A generic zipper with a root object of type <tt>root</tt>.
data Zipper (c :: * -> Constraint) root

-- | Create a zipper. The focus starts at the root of the object.
toZipper :: Rec c a => a -> Zipper c a

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

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

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

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

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

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

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

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

-- | Apply a generic query to the hole.
query :: (forall d. Rec c d => d -> b) -> Zipper c a -> b

-- | Apply a generic transformation to the hole.
trans :: (forall d. Rec c d => d -> d) -> Zipper c a -> Zipper c a

-- | Apply a generic monadic transformation to the hole
transM :: Monad m => (forall d. Rec c d => d -> m d) -> Zipper c a -> m (Zipper c 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 Typeable 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 Typeable b -> Zipper Typeable 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 Typeable b -> Maybe (Zipper Typeable b)
instance GHC.Base.Functor (Data.Generics.Traversable.Zipper.Left c)
instance GHC.Base.Applicative (Data.Generics.Traversable.Zipper.Left c)
