{-# LANGUAGE RankNTypes #-}
module Control.Recursion.GHC ( transverse
, cotransverse
, hoist
) where
import Control.Recursion
transverse :: (Recursive s, Corecursive t, Functor f)
=> (forall a. Base s (f a) -> f (Base t a))
-> s
-> f t
transverse = cata . (fmap embed .)
cotransverse :: (Recursive s, Corecursive t, Functor f)
=> (forall a. f (Base s a) -> Base t (f a))
-> f s
-> t
cotransverse = ana . (. fmap project)
hoist :: (Recursive s, Corecursive t)
=> (forall a. Base s a -> Base t a)
-> s
-> t
hoist = cata . (embed .)
{-# NOINLINE [0] hoist #-}
hoistMu :: (forall a. f a -> g a) -> Mu f -> Mu g
hoistMu η (Mu f) = Mu (f . (. η))
hoistNu :: (forall a. f a -> g a) -> Nu f -> Nu g
hoistNu ν (Nu f x) = Nu (ν . f) x
{-# RULES
"hoist/hoistMu" forall (η :: forall a. f a -> f a) (f :: forall a. (f a -> a) -> a). hoist η (Mu f) = hoistMu η (Mu f);
#-}
{-# RULES
"hoist/hoistNu" forall (η :: forall a. f a -> f a) (f :: a -> f a) x. hoist η (Nu f x) = hoistNu η (Nu f x);
#-}