module Data.Functor.Foldable.Exotic
(
SubHom (..)
, SubType (..)
, CoSubHom (..)
, Dummy (..)
, cataM
, anaM
, hyloM
, dendro
, dendroTri
, symplecto
, chema
, dicata
, micro
) where
import Control.Arrow
import Control.Composition
import Data.Functor.Foldable
class (Functor f, Functor g) => SubHom f g a b where
homo :: (f a -> a) -> (g b -> b) -> (g b -> b)
class SubType b where
switch :: b -> b
class (Functor f, Functor g) => CoSubHom f g a b where
homoCo :: (a -> f a) -> (b -> g b) -> (b -> g b)
class Dummy t where
dummy :: t
symplecto :: (SubHom g f b b, CoSubHom g f a a)
=> (g b -> b)
-> (a -> g a)
-> (f b -> b)
-> (a -> f a)
-> a -> b
symplecto = homoCo -.* (flip . ((.) .* hylo .* homo))
chema :: (CoSubHom (Base t) (Base t') a b, SubType b, Corecursive t')
=> t
-> (a -> Base t a)
-> (b -> Base t' b)
-> b -> t'
chema = const (pseudoana .* homoCo)
where pseudoana g = a where a = embed . fmap (a . switch) . g . switch
dendro :: (SubHom (Base t) (Base t') a b, SubType b, Recursive t')
=> t
-> (Base t a -> a)
-> (Base t' b -> b)
-> t' -> b
dendro = const (pseudocata .* homo)
where pseudocata f = c where c = switch . f . fmap (switch . c) . project
dendroTri :: (SubHom (Base t) (Base t') a b, SubType b, Recursive t', SubHom (Base t'') (Base t) c a, SubType a, Recursive t)
=> t
-> t''
-> (Base t'' c -> c)
-> (Base t a -> a)
-> (Base t' b -> b)
-> t' -> b
dendroTri = fmap const (switch .** homo -.* (fmap <$> dendro))
dicata :: (Recursive a) => (Base a (b, a) -> b) -> (Base a (b, a) -> a) -> a -> b
dicata = fst .** (cata .* (&&&))
micro :: (Corecursive a) => (b -> Either a (Base a b)) -> b -> a
micro = elgot embed
cataM :: (Recursive t, Traversable (Base t), Monad m) => (Base t a -> m a) -> (t -> m a)
cataM phi = c where c = phi <=< (mapM c . project)
anaM :: (Corecursive t, Traversable (Base t), Monad m) => (a -> m (Base t a)) -> (a -> m t)
anaM psi = a where a = (fmap embed . mapM a) <=< psi
hyloM :: (Functor f, Monad m, Traversable f) => (f b -> m b) -> (a -> m (f a)) -> a -> m b
hyloM phi psi = h where h = phi <=< mapM h <=< psi