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

-- | Representing common recursion patterns as higher-order functions
--   
--   Many recursive functions share the same structure, e.g. pattern-match
--   on the input and, depending on the data constructor, either recur on a
--   smaller input or terminate the recursion with the base case. Another
--   one: start with a seed value, use it to produce the first element of
--   an infinite list, and recur on a modified seed in order to produce the
--   rest of the list. Such a structure is called a recursion scheme. Using
--   higher-order functions to implement those recursion schemes makes your
--   code clearer, faster, and safer. See README for details.
@package recursion-schemes
@version 5.2.3

-- | Base Functors for standard types not already expressed as a fixed
--   point.
module Data.Functor.Base

-- | Base functor of [].
data ListF a b
Nil :: ListF a b
Cons :: a -> b -> ListF a b

-- | Base Functor for NonEmpty
data NonEmptyF a b
NonEmptyF :: a -> Maybe b -> NonEmptyF a b
[head] :: NonEmptyF a b -> a
[tail] :: NonEmptyF a b -> Maybe b

-- | Base functor for Tree.
data TreeF a b
NodeF :: a -> ForestF a b -> TreeF a b
type ForestF a b = [b]
instance Data.Bifoldable.Bifoldable Data.Functor.Base.ListF
instance Data.Bifoldable.Bifoldable Data.Functor.Base.NonEmptyF
instance Data.Bifoldable.Bifoldable Data.Functor.Base.TreeF
instance Data.Bifunctor.Bifunctor Data.Functor.Base.ListF
instance Data.Bifunctor.Bifunctor Data.Functor.Base.NonEmptyF
instance Data.Bifunctor.Bifunctor Data.Functor.Base.TreeF
instance Data.Bitraversable.Bitraversable Data.Functor.Base.ListF
instance Data.Bitraversable.Bitraversable Data.Functor.Base.NonEmptyF
instance Data.Bitraversable.Bitraversable Data.Functor.Base.TreeF
instance GHC.Classes.Eq a => Data.Functor.Classes.Eq1 (Data.Functor.Base.ListF a)
instance GHC.Classes.Eq a => Data.Functor.Classes.Eq1 (Data.Functor.Base.NonEmptyF a)
instance GHC.Classes.Eq a => Data.Functor.Classes.Eq1 (Data.Functor.Base.TreeF a)
instance Data.Functor.Classes.Eq2 Data.Functor.Base.ListF
instance Data.Functor.Classes.Eq2 Data.Functor.Base.NonEmptyF
instance Data.Functor.Classes.Eq2 Data.Functor.Base.TreeF
instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Functor.Base.ListF a b)
instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Functor.Base.NonEmptyF a b)
instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Functor.Base.TreeF a b)
instance GHC.Internal.Data.Foldable.Foldable (Data.Functor.Base.ListF a)
instance GHC.Internal.Data.Foldable.Foldable (Data.Functor.Base.NonEmptyF a)
instance GHC.Internal.Data.Foldable.Foldable (Data.Functor.Base.TreeF a)
instance GHC.Internal.Base.Functor (Data.Functor.Base.ListF a)
instance GHC.Internal.Base.Functor (Data.Functor.Base.NonEmptyF a)
instance GHC.Internal.Base.Functor (Data.Functor.Base.TreeF a)
instance GHC.Internal.Generics.Generic1 (Data.Functor.Base.ListF a)
instance GHC.Internal.Generics.Generic1 (Data.Functor.Base.NonEmptyF a)
instance GHC.Internal.Generics.Generic1 (Data.Functor.Base.TreeF a)
instance GHC.Internal.Generics.Generic (Data.Functor.Base.ListF a b)
instance GHC.Internal.Generics.Generic (Data.Functor.Base.NonEmptyF a b)
instance GHC.Internal.Generics.Generic (Data.Functor.Base.TreeF a b)
instance GHC.Classes.Ord a => Data.Functor.Classes.Ord1 (Data.Functor.Base.ListF a)
instance GHC.Classes.Ord a => Data.Functor.Classes.Ord1 (Data.Functor.Base.NonEmptyF a)
instance GHC.Classes.Ord a => Data.Functor.Classes.Ord1 (Data.Functor.Base.TreeF a)
instance Data.Functor.Classes.Ord2 Data.Functor.Base.ListF
instance Data.Functor.Classes.Ord2 Data.Functor.Base.NonEmptyF
instance Data.Functor.Classes.Ord2 Data.Functor.Base.TreeF
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.Functor.Base.ListF a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.Functor.Base.NonEmptyF a b)
instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.Functor.Base.TreeF a b)
instance GHC.Internal.Read.Read a => Data.Functor.Classes.Read1 (Data.Functor.Base.ListF a)
instance GHC.Internal.Read.Read a => Data.Functor.Classes.Read1 (Data.Functor.Base.NonEmptyF a)
instance GHC.Internal.Read.Read a => Data.Functor.Classes.Read1 (Data.Functor.Base.TreeF a)
instance Data.Functor.Classes.Read2 Data.Functor.Base.ListF
instance Data.Functor.Classes.Read2 Data.Functor.Base.NonEmptyF
instance Data.Functor.Classes.Read2 Data.Functor.Base.TreeF
instance (GHC.Internal.Read.Read a, GHC.Internal.Read.Read b) => GHC.Internal.Read.Read (Data.Functor.Base.ListF a b)
instance (GHC.Internal.Read.Read a, GHC.Internal.Read.Read b) => GHC.Internal.Read.Read (Data.Functor.Base.NonEmptyF a b)
instance (GHC.Internal.Read.Read a, GHC.Internal.Read.Read b) => GHC.Internal.Read.Read (Data.Functor.Base.TreeF a b)
instance GHC.Internal.Show.Show a => Data.Functor.Classes.Show1 (Data.Functor.Base.ListF a)
instance GHC.Internal.Show.Show a => Data.Functor.Classes.Show1 (Data.Functor.Base.NonEmptyF a)
instance GHC.Internal.Show.Show a => Data.Functor.Classes.Show1 (Data.Functor.Base.TreeF a)
instance Data.Functor.Classes.Show2 Data.Functor.Base.ListF
instance Data.Functor.Classes.Show2 Data.Functor.Base.NonEmptyF
instance Data.Functor.Classes.Show2 Data.Functor.Base.TreeF
instance (GHC.Internal.Show.Show a, GHC.Internal.Show.Show b) => GHC.Internal.Show.Show (Data.Functor.Base.ListF a b)
instance (GHC.Internal.Show.Show a, GHC.Internal.Show.Show b) => GHC.Internal.Show.Show (Data.Functor.Base.NonEmptyF a b)
instance (GHC.Internal.Show.Show a, GHC.Internal.Show.Show b) => GHC.Internal.Show.Show (Data.Functor.Base.TreeF a b)
instance GHC.Internal.Data.Traversable.Traversable (Data.Functor.Base.ListF a)
instance GHC.Internal.Data.Traversable.Traversable (Data.Functor.Base.NonEmptyF a)
instance GHC.Internal.Data.Traversable.Traversable (Data.Functor.Base.TreeF a)

module Data.Functor.Foldable

-- | Obtain the base functor for a recursive datatype.
--   
--   The core idea of this library is that instead of writing recursive
--   functions on a recursive datatype, we prefer to write non-recursive
--   functions on a related, non-recursive datatype we call the "base
--   functor".
--   
--   For example, [a] is a recursive type, and its corresponding
--   base functor is ListF a:
--   
--   
--   data ListF a b = Nil | Cons a b
--   type instance Base [a] = ListF a
--   
--   
--   The relationship between those two types is that if we replace
--   b with ListF a, we obtain a type which is
--   isomorphic to [a].
type family Base t :: Type -> Type

-- | Base functor of [].
data ListF a b
Nil :: ListF a b
Cons :: a -> b -> ListF a b

-- | A recursive datatype which can be unrolled one recursion layer at a
--   time.
--   
--   For example, a value of type [a] can be unrolled into a
--   ListF a [a]. If that unrolled value is a Cons,
--   it contains another [a] which can be unrolled as well, and so
--   on.
--   
--   Typically, Recursive types also have a Corecursive
--   instance, in which case project and embed are inverses.
class Functor Base t => Recursive t

-- | Unroll a single recursion layer.
--   
--   
--   >>> project [1,2,3]
--   Cons 1 [2,3]
--   
project :: Recursive t => t -> Base t t
($dmproject) :: (Recursive t, Generic t, Generic (Base t t), GCoerce (Rep t) (Rep (Base t t))) => t -> Base t t

-- | A recursive datatype which can be rolled up one recursion layer at a
--   time.
--   
--   For example, a value of type ListF a [a] can be rolled
--   up into a [a]. This [a] can then be used in a
--   Cons to construct another ListF a [a], which
--   can be rolled up as well, and so on.
--   
--   Typically, Corecursive types also have a Recursive
--   instance, in which case embed and project are inverses.
class Functor Base t => Corecursive t

-- | Roll up a single recursion layer.
--   
--   
--   >>> embed (Cons 1 [2,3])
--   [1,2,3]
--   
embed :: Corecursive t => Base t t -> t
($dmembed) :: (Corecursive t, Generic t, Generic (Base t t), GCoerce (Rep (Base t t)) (Rep t)) => Base t t -> t

-- | Folds a recursive type down to a value, one layer at a time.
--   
--   
--   >>> :{
--   let mySum :: [Int] -> Int
--       mySum = fold $ \case
--         Nil -> 0
--         Cons x sumXs -> x + sumXs
--   :}
--   
--   
--   
--   >>> mySum [10,11,12]
--   33
--   
--   
--   In our running example, one layer consists of an Int and a list
--   of recursive positions. In Tree Int, those recursive
--   positions contain sub-trees of type Tree Int. Since we are
--   working one layer at a time, the Base t a -> a function is
--   not given a Tree Int, but a TreeF Int String. That
--   is, each recursive position contains the String resulting from
--   recursively folding the corresponding sub-tree.
--   
--   
--   >>> :{
--   let pprint1 :: Tree Int -> String
--       pprint1 = fold $ \case
--         NodeF i [] -> show i
--         NodeF i ss -> show i ++ ": [" ++ intercalate ", " ss ++ "]"
--   :}
--   
--   
--   
--   >>> putStrLn $ pprint1 myTree
--   0: [1, 2, 3: [31: [311: [3111, 3112]]]]
--   
--   
--   More generally, the t argument is the recursive value, the
--   a is the final result, and the Base t a -> a
--   function explains how to reduce a single layer full of recursive
--   results down to a result.
fold :: Recursive t => (Base t a -> a) -> t -> a

-- | An alias for fold.
--   
--   fold is by far the most common recursion-scheme, because
--   working one layer at a time is the most common strategy for writing a
--   recursive function. But there are also other, rarer strategies.
--   Researchers have given names to the most common strategies, and their
--   name for fold is "catamorphism". They also give its Base t
--   a -> a argument a special name, "(Base t)-algebra".
--   More generally, a function of the form f a -> a is called
--   an "f-algebra".
--   
--   The names might seem intimidating at first, but using the standard
--   nomenclature has benefits. If you program with others, it can be
--   useful to have a shared vocabulary to refer to those recursion
--   patterns. For example, you can discuss which type of recursion is the
--   most appropriate for the problem at hand. Names can also help to
--   structure your thoughts while writing recursive functions.
--   
--   The rest of this module lists a few of the other recursion-schemes
--   which are common enough to have a name. In this section, we restrict
--   our attention to those which fold a recursive structure down to a
--   value. In the examples all functions will be of type Tree Int
--   -> String.
cata :: Recursive t => (Base t a -> a) -> t -> a

-- | A specialization of cata for effectful folds.
--   
--   cataA is the same as cata, but with a more specialized
--   type. The only reason it exists is to make it easier to discover how
--   to use this library with effects.
--   
--   For our running example, let's improve the output format of our
--   pretty-printer by using indentation. To do so, we will need to keep
--   track of the current indentation level. We will do so using a
--   Reader Int effect. Our recursive positions will thus contain
--   Reader Int String actions, not Strings. This means
--   we need to run those actions in order to get the results.
--   
--   
--   >>> :{
--   let pprint2 :: Tree Int -> String
--       pprint2 = flip runReader 0 . cataA go
--         where
--           go :: TreeF Int (Reader Int String)
--              -> Reader Int String
--           go (NodeF i rss) = do
--             -- rss :: [Reader Int String]
--             -- ss  :: [String]
--             ss <- local (+ 2) $ sequence rss
--             indent <- ask
--             let s = replicate indent ' ' ++ "* " ++ show i
--             pure $ intercalate "\n" (s : ss)
--   :}
--   
--   
--   
--   >>> putStrLn $ pprint2 myTree
--   * 0
--     * 1
--     * 2
--     * 3
--       * 31
--         * 311
--           * 3111
--           * 3112
--   
--   
--   The fact that the recursive positions contain Reader actions
--   instead of Strings gives us some flexibility. Here, we are able
--   to increase the indentation by running those actions inside a
--   local block. More generally, we can control the order of
--   their side-effects, interleave them with other effects, etc.
--   
--   A similar technique is to specialize cata so that the result is
--   a function. This makes it possible for data to flow down in addition
--   to up. In this modified version of our running example, the
--   indentation level flows down from the root to the leaves, while the
--   resulting strings flow up from the leaves to the root.
--   
--   
--   >>> :{
--   let pprint3 :: Tree Int -> String
--       pprint3 t = cataA go t 0
--         where
--           go :: TreeF Int (Int -> String)
--              -> Int -> String
--           go (NodeF i fs) indent
--               -- fs :: [Int -> String]
--             = let indent' = indent + 2
--                   ss = map (\f -> f indent') fs
--                   s = replicate indent ' ' ++ "* " ++ show i
--               in intercalate "\n" (s : ss)
--   :}
--   
--   
--   
--   >>> putStrLn $ pprint3 myTree
--   * 0
--     * 1
--     * 2
--     * 3
--       * 31
--         * 311
--           * 3111
--           * 3112
--   
cataA :: Recursive t => (Base t (f a) -> f a) -> t -> f a

-- | A variant of cata in which recursive positions also include the
--   original sub-tree, in addition to the result of folding that sub-tree.
--   
--   For our running example, let's add a number to each node indicating
--   how many children are below it. To do so, we will need to count those
--   nodes from the original sub-tree.
--   
--   
--   >>> :{
--   let pprint4 :: Tree Int -> String
--       pprint4 = flip runReader 0 . para go
--         where
--           go :: TreeF Int (Tree Int, Reader Int String)
--              -> Reader Int String
--           go (NodeF i trss) = do
--             -- trss :: [(Tree Int, Reader Int String)]
--             -- ts   :: [Tree Int]
--             -- rss  :: [Reader Int String]
--             -- ss   :: [String]
--             let (ts, rss) = unzip trss
--             let count = sum $ fmap length ts
--             ss <- local (+ 2) $ sequence rss
--             indent <- ask
--             let s = replicate indent ' '
--                  ++ "* " ++ show i
--                  ++ " (" ++ show count ++ ")"
--             pure $ intercalate "\n" (s : ss)
--   :}
--   
--   
--   
--   >>> putStrLn $ pprint4 myTree
--   * 0 (7)
--     * 1 (0)
--     * 2 (0)
--     * 3 (4)
--       * 31 (3)
--         * 311 (2)
--           * 3111 (0)
--           * 3112 (0)
--   
--   
--   One common use for para is to construct a new tree which reuses
--   most of the sub-trees from the original. In the following example, we
--   insert a new node under the leftmost leaf. This requires allocating
--   new nodes along a path from the root to that leaf, while keeping every
--   other sub-tree untouched.
--   
--   
--   >>> :{
--   let insertLeftmost :: Int -> Tree Int -> Tree Int
--       insertLeftmost new = para go
--         where
--           go :: TreeF Int (Tree Int, Tree Int)
--              -> Tree Int
--           go (NodeF i []) = Node i [Node new []]
--           go (NodeF i ((_orig, recur) : tts))
--               -- tts :: [(Tree Int, Tree Int)]
--             = let (origs, _recurs) = unzip tts
--               in Node i (recur : origs)
--   :}
--   
--   
--   
--   >>> putStrLn $ pprint4 $ insertLeftmost 999 myTree
--   * 0 (8)
--     * 1 (1)
--       * 999 (0)
--     * 2 (0)
--     * 3 (4)
--       * 31 (3)
--         * 311 (2)
--           * 3111 (0)
--           * 3112 (0)
--   
para :: Recursive t => (Base t (t, a) -> a) -> t -> a

-- | A variant of cata which includes the results of all the
--   descendents, not just the direct children.
--   
--   Like para, a sub-tree is provided for each recursive position.
--   Each node in that sub-tree is annotated with the result for that
--   descendent. The Cofree type is used to add those annotations.
--   
--   For our running example, let's recreate GitHub's directory compression
--   algorithm. Notice that in the repository for this package,
--   GitHub displays src/Data/Functor, not src:
--   
--   
--   GitHub does this because src only contains one entry:
--   Data. Similarly, Data only contains one entry:
--   Functor. Functor contains several entries, so the
--   compression stops there. This helps users get to the interesting
--   folders more quickly.
--   
--   Before we use histo, we need to define a helper function
--   rollup. It collects nodes until it reaches a node which
--   doesn't have exactly one child. It also returns the labels of that
--   node's children.
--   
--   
--   >>> :{
--   let rollup :: [Cofree (TreeF node) label]
--              -> ([node], [label])
--       rollup [_ :< NodeF node cofrees] =
--         let (nodes, label) = rollup cofrees
--         in (node : nodes, label)
--       rollup cofrees =
--         ([], fmap extract cofrees)
--   :}
--   
--   
--   
--   >>> let foobar xs = 1 :< NodeF "foo" [2 :< NodeF "bar" xs]
--   
--   >>> rollup [foobar []]
--   (["foo","bar"],[])
--   
--   >>> rollup [foobar [3 :< NodeF "baz" [], 4 :< NodeF "quux" []]]
--   (["foo","bar"],[3,4])
--   
--   
--   The value foobar [] can be interpreted as the tree NodeF
--   "foo" [NodeF "bar" []], plus two annotations. The "foo"
--   node is annotated with 1, while the "bar" node is
--   annotated with 2. When we call histo below, those
--   annotations are recursive results of type Int -> String.
--   
--   
--   >>> :{
--   let pprint5 :: Tree Int -> String
--       pprint5 t = histo go t 0
--         where
--           go :: TreeF Int (Cofree (TreeF Int) (Int -> String))
--              -> Int -> String
--           go (NodeF node cofrees) indent
--               -- cofrees :: [Cofree (TreeF Int) (Int -> String)]
--               -- fs :: [Int -> String]
--             = let indent' = indent + 2
--                   (nodes, fs) = rollup cofrees
--                   ss = map (\f -> f indent') fs
--                   s = replicate indent ' '
--                    ++ "* " ++ intercalate " / " (fmap show (node : nodes))
--               in intercalate "\n" (s : ss)
--   :}
--   
--   
--   
--   >>> putStrLn $ pprint5 myTree
--   * 0
--     * 1
--     * 2
--     * 3 / 31 / 311
--       * 3111
--       * 3112
--   
--   
--   One common use for histo is to cache the value computed for
--   smaller sub-trees. In the Fibonacci example below, the recursive type
--   is Natural, which is isomorphic to [()]. Our annotated
--   sub-tree is thus isomorphic to a list of annotations. In our case,
--   each annotation is the result which was computed for a smaller number.
--   We thus have access to a list which caches all the Fibonacci numbers
--   we have computed so far.
--   
--   
--   >>> :{
--   let fib :: Natural -> Integer
--       fib = histo go
--         where
--           go :: Maybe (Cofree Maybe Integer) -> Integer
--           go Nothing = 1
--           go (Just (_ :< Nothing)) = 1
--           go (Just (fibNMinus1 :< Just (fibNMinus2 :< _)))
--             = fibNMinus1 + fibNMinus2
--   :}
--   
--   
--   
--   >>> fmap fib [0..10]
--   [1,1,2,3,5,8,13,21,34,55,89]
--   
--   
--   In general, Cofree f a can be thought of as a cache that has
--   the same shape as the recursive structure which was given as input.
histo :: Recursive t => (Base t (Cofree (Base t) a) -> a) -> t -> a
zygo :: Recursive t => (Base t b -> b) -> (Base t (b, a) -> a) -> t -> a

-- | A generalization of unfoldr. The starting seed is expanded
--   into a base functor whose recursive positions contain more seeds,
--   which are themselves expanded, and so on.
--   
--   
--   >>> :{
--   
--   >>> let ourEnumFromTo :: Int -> Int -> [Int]
--   
--   >>>     ourEnumFromTo lo hi = ana go lo where
--   
--   >>>         go i = if i > hi then Nil else Cons i (i + 1)
--   
--   >>> :}
--   
--   
--   
--   >>> ourEnumFromTo 1 4
--   [1,2,3,4]
--   
unfold :: Corecursive t => (a -> Base t a) -> a -> t

-- | An alias for unfold.
ana :: Corecursive t => (a -> Base t a) -> a -> t
apo :: Corecursive t => (a -> Base t (Either t a)) -> a -> t
futu :: Corecursive t => (a -> Base t (Free (Base t) a)) -> a -> t

-- | An optimized version of fold f . unfold g.
--   
--   Useful when your recursion structure is shaped like a particular
--   recursive datatype, but you're neither consuming nor producing that
--   recursive datatype. For example, the recursion structure of quick sort
--   is a binary tree, but its input and output is a list, not a binary
--   tree.
--   
--   
--   >>> data BinTreeF a b = Tip | Branch b a b deriving (Functor)
--   
--   
--   
--   >>> :{
--   
--   >>> let quicksort :: Ord a => [a] -> [a]
--   
--   >>>     quicksort = refold merge split where
--   
--   >>>         split []     = Tip
--   
--   >>>         split (x:xs) = let (l, r) = partition (<x) xs in Branch l x r
--   
--   >>> 
--   
--   >>>         merge Tip            = []
--   
--   >>>         merge (Branch l x r) = l ++ [x] ++ r
--   
--   >>> :}
--   
--   
--   
--   >>> quicksort [1,5,2,8,4,9,8]
--   [1,2,4,5,8,8,9]
--   
refold :: Functor f => (f b -> b) -> (a -> f a) -> a -> b

-- | An alias for refold.
hylo :: Functor f => (f b -> b) -> (a -> f a) -> a -> b
chrono :: Functor f => (f (Cofree f b) -> b) -> (a -> f (Free f a)) -> a -> b

-- | Convert from one recursive representation to another.
--   
--   
--   >>> refix ["foo", "bar"] :: Fix (ListF String)
--   Fix (Cons "foo" (Fix (Cons "bar" (Fix Nil))))
--   
refix :: (Recursive s, Corecursive t, Base s ~ Base t) => s -> t

-- | Convert from one recursive type to another.
--   
--   
--   >>> showTree $ hoist (\(NonEmptyF h t) -> NodeF [h] (maybeToList t)) ( 'a' :| "bcd")
--   (a (b (c d)))
--   
hoist :: (Recursive s, Corecursive t) => (forall a. () => Base s a -> Base t a) -> s -> t

-- | An effectful version of hoist.
--   
--   Properties:
--   
--   
--   transverse sequenceA = pure
--   
--   
--   Examples:
--   
--   The weird type of first argument allows user to decide an order of
--   sequencing:
--   
--   
--   >>> transverse (\x -> print (void x) *> sequence x) "foo" :: IO String
--   Cons 'f' ()
--   Cons 'o' ()
--   Cons 'o' ()
--   Nil
--   "foo"
--   
--   
--   
--   >>> transverse (\x -> sequence x <* print (void x)) "foo" :: IO String
--   Nil
--   Cons 'o' ()
--   Cons 'o' ()
--   Cons 'f' ()
--   "foo"
--   
transverse :: (Recursive s, Corecursive t, Functor f) => (forall a. () => Base s (f a) -> f (Base t a)) -> s -> f t

-- | A coeffectful version of hoist.
--   
--   Properties:
--   
--   
--   cotransverse distAna = runIdentity
--   
--   
--   Examples:
--   
--   Stateful transformations:
--   
--   
--   >>> :{
--   cotransverse
--     (\(u, b) -> case b of
--       Nil -> Nil
--       Cons x a -> Cons (if u then toUpper x else x) (not u, a))
--     (True, "foobar") :: String
--   :}
--   "FoObAr"
--   
--   
--   We can implement a variant of zipWith
--   
--   
--   >>> data Pair a = Pair a a deriving Functor
--   
--   
--   
--   >>> :{
--   let zipWith' :: forall a b. (a -> a -> b) -> [a] -> [a] -> [b]
--       zipWith' f xs ys = cotransverse g (Pair xs ys) where
--         g :: Pair (ListF a c) -> ListF b (Pair c)
--         g (Pair Nil        _)          = Nil
--         g (Pair _          Nil)        = Nil
--         g (Pair (Cons x a) (Cons y b)) = Cons (f x y) (Pair a b)
--       :}
--   
--   
--   
--   >>> zipWith' (*) [1,2,3] [4,5,6]
--   [4,10,18]
--   
--   
--   
--   >>> zipWith' (*) [1,2,3] [4,5,6,8]
--   [4,10,18]
--   
--   
--   
--   >>> zipWith' (*) [1,2,3,3] [4,5,6]
--   [4,10,18]
--   
cotransverse :: (Recursive s, Corecursive t, Functor f) => (forall a. () => f (Base s a) -> Base t (f a)) -> f s -> t

-- | Mendler-style iteration
mcata :: (forall y. () => (y -> c) -> f y -> c) -> Fix f -> c

-- | Mendler-style recursion
mpara :: (forall y. () => (y -> c) -> (y -> Fix f) -> f y -> c) -> Fix f -> c

-- | Mendler-style course-of-value iteration
mhisto :: (forall y. () => (y -> c) -> (y -> f y) -> f y -> c) -> Fix f -> c

-- | Mendler-style semi-mutual recursion
mzygo :: (forall y. () => (y -> b) -> f y -> b) -> (forall y. () => (y -> c) -> (y -> b) -> f y -> c) -> Fix f -> c

-- | Mendler-style coiteration
mana :: (forall y. () => (x -> y) -> x -> f y) -> x -> Fix f

-- | Mendler-style corecursion
mapo :: (forall y. () => (Fix f -> y) -> (x -> y) -> x -> f y) -> x -> Fix f

-- | Mendler-style course-of-values coiteration
mfutu :: (forall y. () => (f y -> y) -> (x -> y) -> x -> f y) -> x -> Fix f

-- | Fokkinga's prepromorphism
prepro :: (Recursive t, Corecursive t) => (forall b. () => Base t b -> Base t b) -> (Base t a -> a) -> t -> a

-- | Fokkinga's postpromorphism
postpro :: (Corecursive t, Recursive t) => (forall b. () => Base t b -> Base t b) -> (a -> Base t a) -> a -> t

-- | Elgot algebras
elgot :: Functor f => (f a -> a) -> (b -> Either a (f b)) -> b -> a

-- | Elgot coalgebras:
--   http://comonad.com/reader/2008/elgot-coalgebras/
coelgot :: Functor f => ((a, f b) -> b) -> (a -> f a) -> a -> b

-- | A generalized catamorphism
gfold :: (Recursive t, Comonad w) => (forall b. () => Base t (w b) -> w (Base t b)) -> (Base t (w a) -> a) -> t -> a

-- | A generalized catamorphism
gcata :: (Recursive t, Comonad w) => (forall b. () => Base t (w b) -> w (Base t b)) -> (Base t (w a) -> a) -> t -> a
gpara :: (Recursive t, Corecursive t, Comonad w) => (forall b. () => Base t (w b) -> w (Base t b)) -> (Base t (EnvT t w a) -> a) -> t -> a
ghisto :: (Recursive t, Comonad w) => (forall b. () => Base t (w b) -> w (Base t b)) -> (Base t (CofreeT (Base t) w a) -> a) -> t -> a
gzygo :: (Recursive t, Comonad w) => (Base t b -> b) -> (forall c. () => Base t (w c) -> w (Base t c)) -> (Base t (EnvT b w a) -> a) -> t -> a

-- | A generalized anamorphism
gunfold :: (Corecursive t, Monad m) => (forall b. () => m (Base t b) -> Base t (m b)) -> (a -> Base t (m a)) -> a -> t

-- | A generalized anamorphism
gana :: (Corecursive t, Monad m) => (forall b. () => m (Base t b) -> Base t (m b)) -> (a -> Base t (m a)) -> a -> t
gapo :: Corecursive t => (b -> Base t b) -> (a -> Base t (Either b a)) -> a -> t
gfutu :: (Corecursive t, Functor m, Monad m) => (forall b. () => m (Base t b) -> Base t (m b)) -> (a -> Base t (FreeT (Base t) m a)) -> a -> t

-- | A generalized hylomorphism
grefold :: (Comonad w, Functor f, Monad m) => (forall c. () => f (w c) -> w (f c)) -> (forall d. () => m (f d) -> f (m d)) -> (f (w b) -> b) -> (a -> f (m a)) -> a -> b

-- | A generalized hylomorphism
ghylo :: (Comonad w, Functor f, Monad m) => (forall c. () => f (w c) -> w (f c)) -> (forall d. () => m (f d) -> f (m d)) -> (f (w b) -> b) -> (a -> f (m a)) -> a -> b
gchrono :: (Functor f, Functor w, Functor m, Comonad w, Monad m) => (forall c. () => f (w c) -> w (f c)) -> (forall c. () => m (f c) -> f (m c)) -> (f (CofreeT f w b) -> b) -> (a -> f (FreeT f m a)) -> a -> b
gprepro :: (Recursive t, Corecursive t, Comonad w) => (forall b. () => Base t (w b) -> w (Base t b)) -> (forall c. () => Base t c -> Base t c) -> (Base t (w a) -> a) -> t -> a

-- | A generalized postpromorphism
gpostpro :: (Corecursive t, Recursive t, Monad m) => (forall b. () => m (Base t b) -> Base t (m b)) -> (forall c. () => Base t c -> Base t c) -> (a -> Base t (m a)) -> a -> t
distCata :: Functor f => f (Identity a) -> Identity (f a)
distPara :: Corecursive t => Base t (t, a) -> (t, Base t a)
distParaT :: (Corecursive t, Comonad w) => (forall b. () => Base t (w b) -> w (Base t b)) -> Base t (EnvT t w a) -> EnvT t w (Base t a)
distHisto :: Functor f => f (Cofree f a) -> Cofree f (f a)
distGHisto :: (Functor f, Functor h) => (forall b. () => f (h b) -> h (f b)) -> f (CofreeT f h a) -> CofreeT f h (f a)
distZygo :: Functor f => (f b -> b) -> f (b, a) -> (b, f a)
distZygoT :: (Functor f, Comonad w) => (f b -> b) -> (forall c. () => f (w c) -> w (f c)) -> f (EnvT b w a) -> EnvT b w (f a)
distAna :: Functor f => Identity (f a) -> f (Identity a)
distApo :: Recursive t => Either t (Base t a) -> Base t (Either t a)
distGApo :: Functor f => (b -> f b) -> Either b (f a) -> f (Either b a)
distGApoT :: (Functor f, Functor m) => (b -> f b) -> (forall c. () => m (f c) -> f (m c)) -> ExceptT b m (f a) -> f (ExceptT b m a)
distFutu :: Functor f => Free f (f a) -> f (Free f a)
distGFutu :: (Functor f, Functor h) => (forall b. () => h (f b) -> f (h b)) -> FreeT f h (f a) -> f (FreeT f h a)

-- | Zygohistomorphic prepromorphisms:
--   
--   A corrected and modernized version of
--   http://www.haskell.org/haskellwiki/Zygohistomorphic_prepromorphisms
zygoHistoPrepro :: (Corecursive t, Recursive t) => (Base t b -> b) -> (forall c. () => Base t c -> Base t c) -> (Base t (EnvT b (Cofree (Base t)) a) -> a) -> t -> a
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Corecursive (Control.Comonad.Cofree.Cofree f a)
instance (GHC.Internal.Base.Functor w, GHC.Internal.Base.Functor f) => Data.Functor.Foldable.Corecursive (Control.Comonad.Trans.Cofree.CofreeT f w a)
instance Data.Functor.Foldable.Corecursive (GHC.Internal.Data.Either.Either a b)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Corecursive (Control.Monad.Free.Church.F f a)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Corecursive (Data.Fix.Fix f)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Corecursive (Control.Monad.Free.Free f a)
instance (GHC.Internal.Base.Functor m, GHC.Internal.Base.Functor f) => Data.Functor.Foldable.Corecursive (Control.Monad.Trans.Free.FreeT f m a)
instance Data.Functor.Foldable.Corecursive [a]
instance Data.Functor.Foldable.Corecursive (GHC.Internal.Maybe.Maybe a)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Corecursive (Data.Fix.Mu f)
instance Data.Functor.Foldable.Corecursive GHC.Num.Natural.Natural
instance Data.Functor.Foldable.Corecursive (GHC.Internal.Base.NonEmpty a)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Corecursive (Data.Fix.Nu f)
instance Data.Functor.Foldable.Corecursive (Data.Tree.Tree a)
instance (Data.Functor.Foldable.GCoerce f g, Data.Functor.Foldable.GCoerce f' g') => Data.Functor.Foldable.GCoerce (f GHC.Internal.Generics.:*: f') (g GHC.Internal.Generics.:*: g')
instance (Data.Functor.Foldable.GCoerce f g, Data.Functor.Foldable.GCoerce f' g') => Data.Functor.Foldable.GCoerce (f GHC.Internal.Generics.:+: f') (g GHC.Internal.Generics.:+: g')
instance Data.Functor.Foldable.GCoerce (GHC.Internal.Generics.K1 i c) (GHC.Internal.Generics.K1 j c)
instance Data.Functor.Foldable.GCoerce f g => Data.Functor.Foldable.GCoerce (GHC.Internal.Generics.M1 i c f) (GHC.Internal.Generics.M1 i c' g)
instance Data.Functor.Foldable.GCoerce GHC.Internal.Generics.U1 GHC.Internal.Generics.U1
instance Data.Functor.Foldable.GCoerce GHC.Internal.Generics.V1 GHC.Internal.Generics.V1
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Recursive (Control.Comonad.Cofree.Cofree f a)
instance (GHC.Internal.Base.Functor w, GHC.Internal.Base.Functor f) => Data.Functor.Foldable.Recursive (Control.Comonad.Trans.Cofree.CofreeT f w a)
instance Data.Functor.Foldable.Recursive (GHC.Internal.Data.Either.Either a b)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Recursive (Control.Monad.Free.Church.F f a)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Recursive (Data.Fix.Fix f)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Recursive (Control.Monad.Free.Free f a)
instance (GHC.Internal.Base.Functor m, GHC.Internal.Base.Functor f) => Data.Functor.Foldable.Recursive (Control.Monad.Trans.Free.FreeT f m a)
instance Data.Functor.Foldable.Recursive [a]
instance Data.Functor.Foldable.Recursive (GHC.Internal.Maybe.Maybe a)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Recursive (Data.Fix.Mu f)
instance Data.Functor.Foldable.Recursive GHC.Num.Natural.Natural
instance Data.Functor.Foldable.Recursive (GHC.Internal.Base.NonEmpty a)
instance GHC.Internal.Base.Functor f => Data.Functor.Foldable.Recursive (Data.Fix.Nu f)
instance Data.Functor.Foldable.Recursive (Data.Tree.Tree a)

module Data.Functor.Foldable.TH

-- | Build base functor with a sensible default configuration.
--   
--   e.g.
--   
--   
--   data Expr a
--       = Lit a
--       | Add (Expr a) (Expr a)
--       | Expr a :* [Expr a]
--     deriving (Show)
--   
--   makeBaseFunctor ''Expr
--   
--   
--   will create
--   
--   
--   data ExprF a x
--       = LitF a
--       | AddF x x
--       | x :*$ [x]
--     deriving (Functor, Foldable, Traversable)
--   
--   type instance Base (Expr a) = ExprF a
--   
--   instance Recursive (Expr a) where
--       project (Lit x)   = LitF x
--       project (Add x y) = AddF x y
--       project (x :* y)  = x :*$ y
--   
--   instance Corecursive (Expr a) where
--       embed (LitF x)   = Lit x
--       embed (AddF x y) = Add x y
--       embed (x :*$ y)  = x :* y
--   
--   
--   Notes:
--   
--   makeBaseFunctor works properly only with ADTs. Existentials and
--   GADTs aren't supported, as we don't try to do better than GHC's
--   DeriveFunctor.
--   
--   Allowing makeBaseFunctor to take both Names and
--   Decs as an argument is why it exists as a method in a type
--   class. For trickier data-types, like rose-tree (see also
--   Cofree):
--   
--   
--   data Rose f a = Rose a (f (Rose f a))
--   
--   
--   we can invoke makeBaseFunctor with an instance declaration to
--   provide needed context for instances. (c.f.
--   StandaloneDeriving)
--   
--   
--   makeBaseFunctor [d| instance Functor f => Recursive (Rose f a) |]
--   
--   
--   will create
--   
--   
--   data RoseF f a r = RoseF a (f fr)
--     deriving (Functor, Foldable, Traversable)
--   
--   type instance Base (Rose f a) = RoseF f a
--   
--   instance Functor f => Recursive (Rose f a) where
--     project (Rose x xs) = RoseF x xs
--   
--   instance Functor f => Corecursive (Rose f a) where
--     embed (RoseF x xs) = Rose x xs
--   
--   
--   Some doctests:
--   
--   
--   >>> data Expr a = Lit a | Add (Expr a) (Expr a) | Expr a :* [Expr a]; makeBaseFunctor ''Expr
--   
--   
--   
--   >>> :t AddF
--   AddF :: r -> r -> ExprF a r
--   
--   
--   
--   >>> data Rose f a = Rose a (f (Rose f a)); makeBaseFunctor $ asQ [d| instance Functor f => Recursive (Rose f a) |]
--   
--   
--   
--   >>> :t RoseF
--   RoseF :: a -> f r -> RoseF f a r
--   
--   
--   
--   >>> let rose = Rose 1 (Just (Rose 2 (Just (Rose 3 Nothing))))
--   
--   >>> cata (\(RoseF x f) -> x + maybe 0 id f) rose
--   6
--   
class MakeBaseFunctor a

-- | 
--   makeBaseFunctor = makeBaseFunctorWith baseRules
--   
makeBaseFunctor :: MakeBaseFunctor a => a -> DecsQ

-- | Build base functor with a custom configuration.
makeBaseFunctorWith :: MakeBaseFunctor a => BaseRules -> a -> DecsQ

-- | Rules of renaming data names
data BaseRules

-- | Default BaseRules: append F or $ to data
--   type, constructors and field names.
baseRules :: BaseRules

-- | How to name the base functor type.
--   
--   Default is to append F or $.
baseRulesType :: Functor f => ((Name -> Name) -> f (Name -> Name)) -> BaseRules -> f BaseRules

-- | How to rename the base functor type constructors.
--   
--   Default is to append F or $.
baseRulesCon :: Functor f => ((Name -> Name) -> f (Name -> Name)) -> BaseRules -> f BaseRules

-- | How to rename the base functor type field names (in records).
--   
--   Default is to append F or $.
baseRulesField :: Functor f => ((Name -> Name) -> f (Name -> Name)) -> BaseRules -> f BaseRules
instance Data.Functor.Foldable.TH.MakeBaseFunctor Language.Haskell.TH.Syntax.Dec
instance Data.Functor.Foldable.TH.MakeBaseFunctor a => Data.Functor.Foldable.TH.MakeBaseFunctor [a]
instance Data.Functor.Foldable.TH.MakeBaseFunctor Language.Haskell.TH.Syntax.Name
instance Data.Functor.Foldable.TH.MakeBaseFunctor a => Data.Functor.Foldable.TH.MakeBaseFunctor (Language.Haskell.TH.Syntax.Q a)
