Skip to content

Instantly share code, notes, and snippets.

@holoed
Created March 27, 2016 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save holoed/9b176a0ec803fe01b978 to your computer and use it in GitHub Desktop.
Save holoed/9b176a0ec803fe01b978 to your computer and use it in GitHub Desktop.
Ana-Cata (Hylo) Factorial
{-#LANGUAGE DeriveFunctor#-}
module Main where
fix :: ((a -> b) -> a -> b) -> a -> b
fix f = f (fix f)
data Fix f = In { out :: f (Fix f) }
ana :: Functor f => (a -> f a) -> (a -> Fix f) -> a -> Fix f
ana psi f = In . fmap f . psi
anaRec :: Functor f => (a -> f a) -> a -> Fix f
anaRec psi = fix (ana psi)
cata :: Functor f => (f a -> a) -> (Fix f -> a) -> Fix f -> a
cata psi f = psi . fmap f . out
cataRec :: Functor f => (f a -> a) -> Fix f -> a
cataRec psi = fix (cata psi)
data ListF a b = Empty | Cons a b deriving Functor
type ListR a = Fix (ListF a)
genList :: Int -> ListR Int
genList = anaRec psi
where psi 0 = Empty
psi n = Cons n (n - 1)
cataList :: ListR Int -> Int
cataList = cataRec psi
where psi Empty = 1
psi (Cons n x) = n * x
fac :: Int -> Int
fac = cataList . genList
main :: IO ()
main = print (fac 10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment