module Annotations.F.Fixpoints (
Fix(..), compos,
Algebra, cata,
Coalgebra, ana,
ErrorAlgebra, cascade,
) where
import Annotations.Except
import Data.Monoid
import Data.Traversable
import Control.Monad
newtype Fix fT = In { out :: fT (Fix fT) }
deriving instance Show (f (Fix f)) => Show (Fix f)
deriving instance Eq (f (Fix f)) => Eq (Fix f)
mapFix :: (f (Fix f) -> g (Fix g)) -> Fix f -> Fix g
mapFix f = In . f . out
type Algebra fT aT = fT aT -> aT
cata :: Functor fT => Algebra fT aT -> Fix fT -> aT
cata f = f . fmap (cata f) . out
type Coalgebra fT aT = aT -> fT aT
ana :: Functor fT => Coalgebra fT aT -> aT -> Fix fT
ana f = In . fmap (ana f) . f
compos :: Functor f => (Fix f -> Fix f) -> Fix f -> Fix f
compos = mapFix . fmap
type ErrorAlgebra fT eT aT = fT aT -> Either eT aT
cascade :: (Traversable fT, Monoid eT) =>
ErrorAlgebra fT eT aT -> Algebra fT (Except eT aT)
cascade alg expr = case sequenceA expr of
Failed xs -> Failed xs
OK tree' -> case alg tree' of
Left xs -> Failed xs
Right res -> OK res