{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Control.Functor.HigherOrder where
import Control.Natural
type HAlgebra f g = f g :~> g
type HCoalgebra f g = g :~> f g
class HFunctor (f :: ((* -> *) -> * -> *)) where
hfmap :: (m ~> n) -> f m ~> f n
class HFunctor f => HPointed f where
hreturn :: Functor g => g a -> f g a
class HFunctor f => HCopointed f where
hextract :: Functor g => f g a -> g a
newtype HFix f a = HFix { unfix :: f (HFix f) a }
data HEnvT
(f :: ((* -> *) -> * -> *))
(e :: *)
(g :: (* -> *))
(i :: *) = HEnvT { hask :: !e, hlocal :: f g i }
newtype HMutu
(f :: ((* -> *) -> * -> *))
(g :: ((* -> *) -> * -> *))
(a :: *) = HMutu { unmutu :: f (g (HMutu f g)) a }
instance HFunctor f => HFunctor (HEnvT f a) where
hfmap nt = \fa -> HEnvT (hask fa) ((hfmap nt) (hlocal fa))
instance Functor (f g) => Functor (HEnvT f e g) where
fmap f env = HEnvT (hask env) (fmap f (hlocal env))
type HCofree
(f :: ((* -> *) -> * -> *))
(a :: *) = HFix (HEnvT f a)
hcofree :: a -> f (HCofree f a) b -> HCofree f a b
hcofree a fhc = HFix (HEnvT a fhc)
cataNT :: HFunctor f => HAlgebra f g -> HFix f ~> g
cataNT alg = (unwrapNT alg) . nt
where nt hf = (hfmap (cataNT alg)) (unfix hf)
anaNT :: HFunctor f => HCoalgebra f g -> g ~> HFix f
anaNT coalg g = HFix $ (hfmap (anaNT coalg)) $ (unwrapNT coalg) g
hforgetAlg :: HAlgebra (HEnvT f a) (HFix f)
hforgetAlg = wrapNT $ \env -> HFix $ hlocal env
hforget :: HFunctor f => HCofree f a ~> HFix f
hforget = cataNT hforgetAlg
htagCoalg :: HFunctor f => a -> HCoalgebra (HEnvT f a) (HFix f)
htagCoalg tag = wrapNT $ \hfix -> HEnvT tag (unfix hfix)
htag :: HFunctor f => a -> HFix f ~> HCofree f a
htag tag = anaNT (htagCoalg tag)