{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Data.Functor.Foldable.Monadic
  ( -- * Folding
    cataM
  , preproM
  , paraM
  , zygoM
  , histoM, histoM'
  , dynaM, dynaM', dynaM''

    -- * Unfolding
  , anaM
  , postproM
  , apoM
  , cozygoM
  , futuM, futuM'
  , codynaM, codynaM', codynaM''

    -- * Refolding
  , hyloM, metaM
  , hyloM', metaM'
  , chronoM, cochronoM
  , chronoM' -- cochronoM'

    -- * Generalized Folding
  , gcataM, gcataM'

    -- * Others
  , mutuM, comutuM
  , mutuM', comutuM'
  , cascadeM, iterateM
  ) where

import           Control.Comonad              (Comonad (..))
import           Control.Comonad.Cofree       (Cofree (..))
import qualified Control.Comonad.Trans.Cofree as CF (CofreeF (..))
import           Control.Monad                ((<=<), liftM, liftM2)
import           Control.Monad.Free           (Free (..))
import qualified Control.Monad.Trans.Free     as FR (FreeF (..))
import           Data.Functor.Foldable        (Recursive (..), Corecursive (..), Base)

-- | catamorphism
cataM :: (Monad m, Traversable (Base t), Recursive t)
      => (Base t a -> m a) -- ^ algebra
      -> t -> m a
cataM :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> t -> m a
cataM Base t a -> m a
phi = t -> m a
h
  where h :: t -> m a
h = Base t a -> m a
phi forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM t -> m a
h forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project

-- | anamorphism
anaM :: (Monad m, Traversable (Base t), Corecursive t)
     => (a -> m (Base t a)) -- ^ coalgebra
     -> a -> m t
anaM :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM a -> m (Base t a)
psi = a -> m t
h
  where h :: a -> m t
h = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Corecursive t => Base t t -> t
embed forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> m t
h forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m (Base t a)
psi

-- | paramorphism
paraM :: (Monad m, Traversable (Base t), Recursive t)
      => (Base t (t, a) -> m a) -- ^ algebra
      -> t -> m a
paraM :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t (t, a) -> m a) -> t -> m a
paraM Base t (t, a) -> m a
phi = t -> m a
h
  where h :: t -> m a
h = Base t (t, a) -> m a
phi forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. Monad m => a -> m a
return forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> t -> m a
h) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project

-- | apomorphism
apoM :: (Monad m, Traversable (Base t), Corecursive t)
     => (a -> m (Base t (Either t a))) -- ^ coalgebra
     -> a -> m t
apoM :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t (Either t a))) -> a -> m t
apoM a -> m (Base t (Either t a))
psi = a -> m t
h
  where h :: a -> m t
h = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Corecursive t => Base t t -> t
embed forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall (m :: * -> *) a. Monad m => a -> m a
return a -> m t
h) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m (Base t (Either t a))
psi

-- | histomorphism on anamorphism variant
histoM :: (Monad m, Traversable (Base t), Recursive t)
       => (Base t (Cofree (Base t) a) -> m a) -- ^ algebra
       -> t -> m a
histoM :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t (Cofree (Base t) a) -> m a) -> t -> m a
histoM Base t (Cofree (Base t) a) -> m a
phi = t -> m a
h
  where h :: t -> m a
h = Base t (Cofree (Base t) a) -> m a
phi forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM t -> m (Cofree (Base t) a)
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project
        f :: t -> m (Cofree (Base t) a)
f = forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM (forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall (f :: * -> *) a b. a -> f b -> CofreeF f a b
(CF.:<) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> t -> m a
h forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project)

-- | histomorphism on catamorphism variant
histoM' :: (Monad m, Traversable (Base t), Recursive t)
        => (Base t (Cofree (Base t) a) -> m a) -- ^ algebra
        -> t -> m a
histoM' :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t (Cofree (Base t) a) -> m a) -> t -> m a
histoM' Base t (Cofree (Base t) a) -> m a
phi = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (w :: * -> *) a. Comonad w => w a -> a
extract forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> t -> m a
cataM Base t (Cofree (Base t) a) -> m (Cofree (Base t) a)
f
  where f :: Base t (Cofree (Base t) a) -> m (Cofree (Base t) a)
f = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall (f :: * -> *) a. a -> f (Cofree f a) -> Cofree f a
(:<) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Base t (Cofree (Base t) a) -> m a
phi forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return

-- | futumorphism on catamorphism variant
futuM :: (Monad m, Traversable (Base t), Corecursive t)
      => (a -> m (Base t (Free (Base t) a))) -- ^ coalgebra
      -> a -> m t
futuM :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t (Free (Base t) a))) -> a -> m t
futuM a -> m (Base t (Free (Base t) a))
psi = a -> m t
h
  where h :: a -> m t
h = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Corecursive t => Base t t -> t
embed forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Free (Base t) a -> m t
f forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m (Base t (Free (Base t) a))
psi
        f :: Free (Base t) a -> m t
f = forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> t -> m a
cataM forall a b. (a -> b) -> a -> b
$ \case
          FR.Pure  a
a -> a -> m t
h a
a
          FR.Free Base t t
fb -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall t. Corecursive t => Base t t -> t
embed Base t t
fb)

-- | futumorphism on anamorphism variant
futuM' :: (Monad m, Traversable (Base t), Corecursive t)
       => (a -> m (Base t (Free (Base t) a))) -- ^ coalgebra
       -> a -> m t
futuM' :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t (Free (Base t) a))) -> a -> m t
futuM' a -> m (Base t (Free (Base t) a))
psi = forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM Free (Base t) a -> m (Base t (Free (Base t) a))
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. a -> Free f a
Pure
  where f :: Free (Base t) a -> m (Base t (Free (Base t) a))
f (Pure  a
a) = a -> m (Base t (Free (Base t) a))
psi a
a
        f (Free Base t (Free (Base t) a)
fb) = forall (m :: * -> *) a. Monad m => a -> m a
return Base t (Free (Base t) a)
fb

-- | zygomorphism
zygoM :: (Monad m, Traversable (Base t), Recursive t)
      => (Base t a -> m a)      -- ^ algebra for fst
      -> (Base t (a, b) -> m b) -- ^ algebra for snd from product
      -> t -> m b
zygoM :: forall (m :: * -> *) t a b.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> (Base t (a, b) -> m b) -> t -> m b
zygoM Base t a -> m a
f Base t (a, b) -> m b
phi = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> t -> m a
cataM Base t (a, b) -> m (a, b)
g
  where g :: Base t (a, b) -> m (a, b)
g = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Base t a -> m a
f forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Base t (a, b) -> m b
phi

-- | cozygomorphism
cozygoM :: (Monad m, Traversable (Base t), Corecursive t)
        => (a -> m (Base t a))            -- ^ coalgebra for fst
        -> (b -> m (Base t (Either a b))) -- ^ coalgebra for snd to coproduct
        -> b -> m t
cozygoM :: forall (m :: * -> *) t a b.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> (b -> m (Base t (Either a b))) -> b -> m t
cozygoM a -> m (Base t a)
f b -> m (Base t (Either a b))
psi = forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM Either a b -> m (Base t (Either a b))
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right
  where g :: Either a b -> m (Base t (Either a b))
g = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. a -> Either a b
Left forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m (Base t a)
f) b -> m (Base t (Either a b))
psi

-- | hylomorphism on recursive variant
hyloM :: (Monad m, Traversable t)
      => (t b -> m b)   -- ^ algebra
      -> (a -> m (t a)) -- ^ coalgebra
      -> a -> m b
hyloM :: forall (m :: * -> *) (t :: * -> *) b a.
(Monad m, Traversable t) =>
(t b -> m b) -> (a -> m (t a)) -> a -> m b
hyloM t b -> m b
phi a -> m (t a)
psi = a -> m b
h
  where h :: a -> m b
h = t b -> m b
phi forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> m b
h forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m (t a)
psi

-- | hylomorphism on combination variant of ana to cata
hyloM' :: forall m t a b. (Monad m, Traversable (Base t), Recursive t, Corecursive t)
       => (Base t b -> m b)   -- ^ algebra
       -> (a -> m (Base t a)) -- ^ coalgebra
       -> a -> m b
hyloM' :: forall (m :: * -> *) t a b.
(Monad m, Traversable (Base t), Recursive t, Corecursive t) =>
(Base t b -> m b) -> (a -> m (Base t a)) -> a -> m b
hyloM' Base t b -> m b
phi a -> m (Base t a)
psi = (forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> t -> m a
cataM Base t b -> m b
phi :: t -> m b) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM a -> m (Base t a)
psi :: a -> m t)

-- | metamorphism on recursive variant
metaM :: (Monad m, Traversable (Base t), Recursive s, Corecursive t, Base s ~ Base t)
      => (Base t t -> m t)   -- ^ algebra
      -> (s -> m (Base s s)) -- ^ coalgebra
      -> s -> m t
metaM :: forall (m :: * -> *) t s.
(Monad m, Traversable (Base t), Recursive s, Corecursive t,
 Base s ~ Base t) =>
(Base t t -> m t) -> (s -> m (Base s s)) -> s -> m t
metaM Base t t -> m t
_phi s -> m (Base s s)
_psi = s -> m t
h
  where h :: s -> m t
h = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Corecursive t => Base t t -> t
embed forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM s -> m t
h forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project

-- | metamorphism on combination variant of cata to ana
metaM' :: (Monad m, Corecursive c, Traversable (Base c), Traversable (Base t), Recursive t)
       => (Base t a -> m a)   -- ^ algebra
       -> (a -> m (Base c a)) -- ^ coalgebra
       -> t -> m c
metaM' :: forall (m :: * -> *) c t a.
(Monad m, Corecursive c, Traversable (Base c),
 Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> (a -> m (Base c a)) -> t -> m c
metaM' Base t a -> m a
phi a -> m (Base c a)
psi = forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM a -> m (Base c a)
psi forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> t -> m a
cataM Base t a -> m a
phi

-- | chronomorphism on recursive variant over hylomorphism
chronoM' :: (Monad m, Traversable t)
         => (t (Cofree t b) -> m b) -- ^ algebra
         -> (a -> m (t (Free t a))) -- ^ coalgebra
         -> a -> m b
chronoM' :: forall (m :: * -> *) (t :: * -> *) b a.
(Monad m, Traversable t) =>
(t (Cofree t b) -> m b) -> (a -> m (t (Free t a))) -> a -> m b
chronoM' t (Cofree t b) -> m b
phi a -> m (t (Free t a))
psi = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (w :: * -> *) a. Comonad w => w a -> a
extract forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) (t :: * -> *) b a.
(Monad m, Traversable t) =>
(t b -> m b) -> (a -> m (t a)) -> a -> m b
hyloM t (Cofree t b) -> m (Cofree t b)
f Free t a -> m (t (Free t a))
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. a -> Free f a
Pure
  where f :: t (Cofree t b) -> m (Cofree t b)
f = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall (f :: * -> *) a. a -> f (Cofree f a) -> Cofree f a
(:<) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> t (Cofree t b) -> m b
phi forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return
        g :: Free t a -> m (t (Free t a))
g (Pure  a
a) = a -> m (t (Free t a))
psi a
a
        g (Free t (Free t a)
fb) = forall (m :: * -> *) a. Monad m => a -> m a
return t (Free t a)
fb

-- | chronomorphism on combination variant of futu to hist
chronoM :: forall m t a b. (Monad m, Traversable (Base t), Recursive t, Corecursive t)
        => (Base t (Cofree (Base t) b) -> m b) -- ^ algebra
        -> (a -> m (Base t (Free (Base t) a))) -- ^ coalgebra
        -> a -> m b
chronoM :: forall (m :: * -> *) t a b.
(Monad m, Traversable (Base t), Recursive t, Corecursive t) =>
(Base t (Cofree (Base t) b) -> m b)
-> (a -> m (Base t (Free (Base t) a))) -> a -> m b
chronoM Base t (Cofree (Base t) b) -> m b
phi a -> m (Base t (Free (Base t) a))
psi = (forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t (Cofree (Base t) a) -> m a) -> t -> m a
histoM Base t (Cofree (Base t) b) -> m b
phi :: t -> m b) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t (Free (Base t) a))) -> a -> m t
futuM a -> m (Base t (Free (Base t) a))
psi :: a -> m t)

-- | cochronomorphism on combination variant of histo to futu
cochronoM :: (Monad m, Corecursive c, Traversable (Base c), Traversable (Base t), Recursive t)
          => (Base t (Cofree (Base t) a) -> m a) -- ^ algebra
          -> (a -> m (Base c (Free (Base c) a))) -- ^ coalgebra
          -> t -> m c
cochronoM :: forall (m :: * -> *) c t a.
(Monad m, Corecursive c, Traversable (Base c),
 Traversable (Base t), Recursive t) =>
(Base t (Cofree (Base t) a) -> m a)
-> (a -> m (Base c (Free (Base c) a))) -> t -> m c
cochronoM Base t (Cofree (Base t) a) -> m a
phi a -> m (Base c (Free (Base c) a))
psi = forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t (Free (Base t) a))) -> a -> m t
futuM a -> m (Base c (Free (Base c) a))
psi forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t (Cofree (Base t) a) -> m a) -> t -> m a
histoM Base t (Cofree (Base t) a) -> m a
phi

-- | dynamorphism on recursive variant over chronomorphism
dynaM :: (Monad m, Traversable (Base t), Recursive t, Corecursive t)
      => (Base t (Cofree (Base t) b) -> m b) -- ^ algebra
      -> (a -> m (Base t a))                 -- ^ coalgebra
      -> a -> m b
dynaM :: forall (m :: * -> *) t b a.
(Monad m, Traversable (Base t), Recursive t, Corecursive t) =>
(Base t (Cofree (Base t) b) -> m b)
-> (a -> m (Base t a)) -> a -> m b
dynaM Base t (Cofree (Base t) b) -> m b
phi a -> m (Base t a)
psi = forall (m :: * -> *) (t :: * -> *) b a.
(Monad m, Traversable t) =>
(t (Cofree t b) -> m b) -> (a -> m (t (Free t a))) -> a -> m b
chronoM' Base t (Cofree (Base t) b) -> m b
phi (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (f :: * -> *) a. a -> Free f a
Pure forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m (Base t a)
psi)

-- | dynamorphism on combination variant of ana to histo
dynaM' :: forall m t a c. (Monad m, Traversable (Base t), Recursive t, Corecursive t)
       => (Base t (Cofree (Base t) c) -> m c) -- ^ algebra
       -> (a -> m (Base t a))                 -- ^ coalgebra
       -> a -> m c
dynaM' :: forall (m :: * -> *) t a c.
(Monad m, Traversable (Base t), Recursive t, Corecursive t) =>
(Base t (Cofree (Base t) c) -> m c)
-> (a -> m (Base t a)) -> a -> m c
dynaM' Base t (Cofree (Base t) c) -> m c
phi a -> m (Base t a)
psi = (forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t (Cofree (Base t) a) -> m a) -> t -> m a
histoM Base t (Cofree (Base t) c) -> m c
phi :: t -> m c) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM a -> m (Base t a)
psi :: a -> m t)

-- | dynamorphism on recursive variant over hylomorphism
dynaM'' :: (Monad m, Traversable t)
        => (t (Cofree t c) -> m c) -- ^ algebra
        -> (a -> m (t a))          -- ^ coalgebra
        -> a -> m c
dynaM'' :: forall (m :: * -> *) (t :: * -> *) c a.
(Monad m, Traversable t) =>
(t (Cofree t c) -> m c) -> (a -> m (t a)) -> a -> m c
dynaM'' t (Cofree t c) -> m c
phi a -> m (t a)
psi = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (w :: * -> *) a. Comonad w => w a -> a
extract forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) (t :: * -> *) b a.
(Monad m, Traversable t) =>
(t b -> m b) -> (a -> m (t a)) -> a -> m b
hyloM t (Cofree t c) -> m (Cofree t c)
f a -> m (t a)
psi
  where f :: t (Cofree t c) -> m (Cofree t c)
f = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall (f :: * -> *) a. a -> f (Cofree f a) -> Cofree f a
(:<) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> t (Cofree t c) -> m c
phi forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return

-- | codynamorphism on recursive variant over chronomorphism
codynaM :: (Monad m, Traversable t)
        => (t b -> m b)            -- ^ algebra
        -> (a -> m (t (Free t a))) -- ^ coalgebra
        -> a -> m b
codynaM :: forall (m :: * -> *) (t :: * -> *) b a.
(Monad m, Traversable t) =>
(t b -> m b) -> (a -> m (t (Free t a))) -> a -> m b
codynaM t b -> m b
phi a -> m (t (Free t a))
psi = forall (m :: * -> *) (t :: * -> *) b a.
(Monad m, Traversable t) =>
(t (Cofree t b) -> m b) -> (a -> m (t (Free t a))) -> a -> m b
chronoM' (t b -> m b
phi forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (w :: * -> *) a. Comonad w => w a -> a
extract) a -> m (t (Free t a))
psi

-- | codynamorphism on combination variant of histo to ana
codynaM' :: (Monad m, Corecursive c, Traversable (Base c), Traversable (Base t), Recursive t)
         => (Base t (Cofree (Base t) a) -> m a) -- ^ algebra
         -> (a -> m (Base c a))                 -- ^ coalgebra
         -> t -> m c
codynaM' :: forall (m :: * -> *) c t a.
(Monad m, Corecursive c, Traversable (Base c),
 Traversable (Base t), Recursive t) =>
(Base t (Cofree (Base t) a) -> m a)
-> (a -> m (Base c a)) -> t -> m c
codynaM' Base t (Cofree (Base t) a) -> m a
phi a -> m (Base c a)
psi = forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM a -> m (Base c a)
psi forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t (Cofree (Base t) a) -> m a) -> t -> m a
histoM Base t (Cofree (Base t) a) -> m a
phi

-- | codynamorphism on recursive variant over hylomorphism
codynaM'' :: (Monad m, Traversable t)
          => (t b -> m b)            -- ^ algebra
          -> (a -> m (t (Free t a))) -- ^ coalgebra
          -> a -> m b
codynaM'' :: forall (m :: * -> *) (t :: * -> *) b a.
(Monad m, Traversable t) =>
(t b -> m b) -> (a -> m (t (Free t a))) -> a -> m b
codynaM'' t b -> m b
phi a -> m (t (Free t a))
psi = forall (m :: * -> *) (t :: * -> *) b a.
(Monad m, Traversable t) =>
(t b -> m b) -> (a -> m (t a)) -> a -> m b
hyloM t b -> m b
phi Free t a -> m (t (Free t a))
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. a -> Free f a
Pure
  where g :: Free t a -> m (t (Free t a))
g (Pure  a
a) = a -> m (t (Free t a))
psi a
a
        g (Free t (Free t a)
fb) = forall (m :: * -> *) a. Monad m => a -> m a
return t (Free t a)
fb

-- | mutumorphism on mutual recursive
mutuM :: (Monad m, Traversable (Base t), Recursive t)
      => (Base t (a, b) -> m b) -- ^ algebra
      -> (Base t (a, b) -> m a) -- ^ algebra
      -> t -> m b
mutuM :: forall (m :: * -> *) t a b.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t (a, b) -> m b) -> (Base t (a, b) -> m a) -> t -> m b
mutuM Base t (a, b) -> m b
q Base t (a, b) -> m a
p = forall (m :: * -> *) t a b.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t (a, b) -> m b) -> (Base t (a, b) -> m a) -> t -> m b
v Base t (a, b) -> m b
q Base t (a, b) -> m a
p
  where u :: (Base a (a1, a2) -> m a1) -> (Base a (a1, a2) -> m a2) -> a -> m a1
u Base a (a1, a2) -> m a1
f Base a (a1, a2) -> m a2
g = Base a (a1, a2) -> m a1
f forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Base a (a1, a2) -> m a1) -> (Base a (a1, a2) -> m a2) -> a -> m a1
u Base a (a1, a2) -> m a1
f Base a (a1, a2) -> m a2
g forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Base a (a1, a2) -> m a2) -> (Base a (a1, a2) -> m a1) -> a -> m a2
v Base a (a1, a2) -> m a2
g Base a (a1, a2) -> m a1
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project
        v :: (Base a (a1, a2) -> m a2) -> (Base a (a1, a2) -> m a1) -> a -> m a2
v Base a (a1, a2) -> m a2
g Base a (a1, a2) -> m a1
f = Base a (a1, a2) -> m a2
g forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Base a (a1, a2) -> m a1) -> (Base a (a1, a2) -> m a2) -> a -> m a1
u Base a (a1, a2) -> m a1
f Base a (a1, a2) -> m a2
g forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Base a (a1, a2) -> m a2) -> (Base a (a1, a2) -> m a1) -> a -> m a2
v Base a (a1, a2) -> m a2
g Base a (a1, a2) -> m a1
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project

-- | mutumorphism on recursive variant over catamorphism
mutuM' :: (Monad m, Traversable (Base t), Recursive t)
       => (a -> b)          -- ^ project
       -> (Base t a -> m a) -- ^ algebra
       -> t -> m b
mutuM' :: forall (m :: * -> *) t a b.
(Monad m, Traversable (Base t), Recursive t) =>
(a -> b) -> (Base t a -> m a) -> t -> m b
mutuM' a -> b
f Base t a -> m a
phi = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> t -> m a
cataM Base t a -> m a
phi

-- | comutumorphism on comutual recursive
comutuM :: (Monad m, Traversable (Base t), Corecursive t)
        => (b -> m (Base t (Either a b))) -- ^ coalgebra
        -> (a -> m (Base t (Either a b))) -- ^ coalgebra
        -> b -> m t
comutuM :: forall (m :: * -> *) t b a.
(Monad m, Traversable (Base t), Corecursive t) =>
(b -> m (Base t (Either a b)))
-> (a -> m (Base t (Either a b))) -> b -> m t
comutuM b -> m (Base t (Either a b))
q a -> m (Base t (Either a b))
p = forall {m :: * -> *} {b} {a} {b}.
(Monad m, Corecursive b, Traversable (Base b)) =>
(b -> m (Base b (Either a b)))
-> (a -> m (Base b (Either a b))) -> b -> m b
v b -> m (Base t (Either a b))
q a -> m (Base t (Either a b))
p
  where u :: (a -> m (Base b (Either a b)))
-> (b -> m (Base b (Either a b))) -> a -> m b
u a -> m (Base b (Either a b))
f b -> m (Base b (Either a b))
g = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall t. Corecursive t => Base t t -> t
embed forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((a -> m (Base b (Either a b)))
-> (b -> m (Base b (Either a b))) -> a -> m b
u a -> m (Base b (Either a b))
f b -> m (Base b (Either a b))
g) ((b -> m (Base b (Either a b)))
-> (a -> m (Base b (Either a b))) -> b -> m b
v b -> m (Base b (Either a b))
g a -> m (Base b (Either a b))
f)) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m (Base b (Either a b))
f
        v :: (b -> m (Base b (Either a b)))
-> (a -> m (Base b (Either a b))) -> b -> m b
v b -> m (Base b (Either a b))
g a -> m (Base b (Either a b))
f = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall t. Corecursive t => Base t t -> t
embed forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((a -> m (Base b (Either a b)))
-> (b -> m (Base b (Either a b))) -> a -> m b
u a -> m (Base b (Either a b))
f b -> m (Base b (Either a b))
g) ((b -> m (Base b (Either a b)))
-> (a -> m (Base b (Either a b))) -> b -> m b
v b -> m (Base b (Either a b))
g a -> m (Base b (Either a b))
f)) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< b -> m (Base b (Either a b))
g

-- | comutumorphism on recursive variant over anamorphism
comutuM' :: (Monad m, Traversable (Base t), Corecursive t)
         => (b -> a)            -- ^ embed
         -> (a -> m (Base t a)) -- ^ coalgebra
         -> b -> m t
comutuM' :: forall (m :: * -> *) t b a.
(Monad m, Traversable (Base t), Corecursive t) =>
(b -> a) -> (a -> m (Base t a)) -> b -> m t
comutuM' b -> a
f a -> m (Base t a)
psi = forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM a -> m (Base t a)
psi forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a
f

-- | prepromorphism
preproM :: (Monad m, Traversable (Base t), Recursive t, Corecursive t)
        => (Base t t -> m (Base t t)) -- ^ monadic natural transformation
        -> (Base t a -> m a)          -- ^ algebra
        -> t -> m a
preproM :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t, Corecursive t) =>
(Base t t -> m (Base t t)) -> (Base t a -> m a) -> t -> m a
preproM Base t t -> m (Base t t)
h Base t a -> m a
phi = t -> m a
u
  where u :: t -> m a
u = Base t a -> m a
phi forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM t -> m a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project
        f :: t -> m a
f = t -> m a
u forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> t -> m a
cataM (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Corecursive t => Base t t -> t
embed forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Base t t -> m (Base t t)
h)

-- | postpromorphism
postproM :: (Monad m, Traversable (Base t), Recursive t, Corecursive t)
         => (Base t t -> m (Base t t)) -- ^ monadic natural transformation
         -> (a -> m (Base t a))        -- ^ coalgebra
         -> a -> m t
postproM :: forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t, Corecursive t) =>
(Base t t -> m (Base t t)) -> (a -> m (Base t a)) -> a -> m t
postproM Base t t -> m (Base t t)
h a -> m (Base t a)
psi = a -> m t
u
  where u :: a -> m t
u = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Corecursive t => Base t t -> t
embed forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> m t
f forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m (Base t a)
psi
        f :: a -> m t
f = forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Corecursive t) =>
(a -> m (Base t a)) -> a -> m t
anaM (Base t t -> m (Base t t)
h forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m t
u

-- | cascade (a.k.a supermap)
cascadeM :: (Monad m, Corecursive (f a), Traversable (Base (f a)), Traversable f, Recursive (f a))
         => (a -> m a) -- ^ pre-operator
         -> f a -> m (f a)
cascadeM :: forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Corecursive (f a), Traversable (Base (f a)),
 Traversable f, Recursive (f a)) =>
(a -> m a) -> f a -> m (f a)
cascadeM a -> m a
f = f a -> m (f a)
u
  where u :: f a -> m (f a)
u = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Corecursive t => Base t t -> t
embed forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM f a -> m (f a)
u forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> m a
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project

-- | iterate
iterateM :: (Monad m, Corecursive (f a), Traversable (Base (f a)), Traversable f, Recursive (f a))
         => (a -> m a) -- ^ post-operator
         -> f a -> m (f a)
iterateM :: forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Corecursive (f a), Traversable (Base (f a)),
 Traversable f, Recursive (f a)) =>
(a -> m a) -> f a -> m (f a)
iterateM a -> m a
f = f a -> m (f a)
u
  where u :: f a -> m (f a)
u = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Corecursive t => Base t t -> t
embed forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> m a
f) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM f a -> m (f a)
u forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project


-- | generalized catamorphism
gcataM :: (Monad m, Comonad w, Traversable w, Traversable (Base t), Recursive t, b ~ w a)
       => (Base t (w b) -> m (w (Base t b))) -- ^ Distributive (Base t) w b
       -> (Base t (w a) -> m a)              -- ^ algebra
       -> t -> m a
gcataM :: forall (m :: * -> *) (w :: * -> *) t b a.
(Monad m, Comonad w, Traversable w, Traversable (Base t),
 Recursive t, b ~ w a) =>
(Base t (w b) -> m (w (Base t b)))
-> (Base t (w a) -> m a) -> t -> m a
gcataM Base t (w b) -> m (w (Base t b))
k Base t (w a) -> m a
g = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall (w :: * -> *) a. Comonad w => w a -> a
extract forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) t a.
(Monad m, Traversable (Base t), Recursive t) =>
(Base t a -> m a) -> t -> m a
cataM Base t (w a) -> m (w a)
phi
  where phi :: Base t (w a) -> m (w a)
phi = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Base t (w a) -> m a
g forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Base t (w b) -> m (w (Base t b))
k forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate

-- | generalized catamorphism variant
gcataM' :: (Monad m, Comonad w, Traversable w, Traversable (Base t), Recursive t, b ~ w a)
        => (Base t (w b) -> m (w (Base t b))) -- ^ Distributive (Base t) w b
        -> (Base t (w a) -> m a)              -- ^ algebra
        -> t -> m a
gcataM' :: forall (m :: * -> *) (w :: * -> *) t b a.
(Monad m, Comonad w, Traversable w, Traversable (Base t),
 Recursive t, b ~ w a) =>
(Base t (w b) -> m (w (Base t b)))
-> (Base t (w a) -> m a) -> t -> m a
gcataM' Base t (w b) -> m (w (Base t b))
k Base t (w a) -> m a
g = Base t (w a) -> m a
g forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (w :: * -> *) a. Comonad w => w a -> a
extract forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< t -> m (w (Base t (w a)))
c
  where c :: t -> m (w (Base t (w a)))
c = Base t (w b) -> m (w (Base t b))
k forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM t -> m (w (w a))
u forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Recursive t => t -> Base t t
project
        u :: t -> m (w (w a))
u = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Base t (w a) -> m a
g forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< t -> m (w (Base t (w a)))
c