module Control.Morphism.Ana where
import Control.Category.Hask
import Control.Functor
import Control.Functor.Algebra
import Control.Functor.Extras
import Control.Functor.Fix
import Control.Functor.HigherOrder
import Control.Comonad ()
import Control.Monad.Identity
ana :: Functor f => Coalgebra f a -> a -> FixF f
ana g = InF . fmap (ana g) . g
g_ana :: (Functor f, Monad m) => Dist m f -> GCoalgebra f m a -> a -> FixF f
g_ana k g = a . return where a = InF . fmap (a . join) . k . liftM g
distAna :: Functor f => Dist Identity f
distAna = fmap Identity . runIdentity
biana :: Bifunctor f Hask Hask Hask => Coalgebra (f b) a -> a -> Fix f b
biana g = InB . bimap id (biana g) . g
g_biana :: (Bifunctor f Hask Hask Hask, Monad m) => Dist m (f b) -> GCoalgebra (f b) m a -> a -> Fix f b
g_biana k g = a . return where a = InB . bimap id (a . join) . k . liftM g
hana :: HFunctor f => HCoalgebra f a -> a :~> FixH f
hana g = InH . hfmap (hana g) . g