yaya-0.2.1.2: src/Yaya/Experimental/Foldable.hs
-- | This shows how `Data.Foldable.Foldable` is basically `Recursive`
-- specialized to lists. The true operation of `Data.Foldable.Foldable` is
-- `Data.Foldable.toList`.
--
-- As these few operations have the usual signatures, the rest of the type
-- class can be implemented in the as in @base@.
module Yaya.Experimental.Foldable where
import Control.Monad.Trans.Free
import Yaya.Fold
import Yaya.Fold.Common
import Yaya.Pattern
foldMap :: (Recursive t (XNor a), Monoid m) => (a -> m) -> t -> m
foldMap = cata . lowerMonoid
-- | This class represents the ability of a structure to be converted to a
-- list. It is equivalent to `Data.Foldable.Foldable`, but designed to
-- illustrate the representation of `Data.Foldable.Foldable` as `Recursive`
-- specialized to lists.
class Listable f where
naturalList :: f a b -> Free (XNor a) b
-- toColist :: (Projectable t (f a), Corecursive u (XNor a)) => t -> u
-- toColist = elgotAna seqFree (naturalList . project)
-- toList :: (Recursive t (f a), Steppable u (XNor a)) => t -> u
-- toList = cata (embed . unFree . naturalList)
-- FIXME: Use @cata . liftCoEnv@ instead of `iter`.
-- | This is simply `cata` applied to a list – the function is the @Cons@
-- case, while the initial value is the @Nil@ case.
foldr :: (Listable f, Recursive t (f a)) => (a -> b -> b) -> b -> t -> b
foldr f b =
cata (iter (\case
Neither -> b
Both a r -> f a r)
. naturalList)
-- | Simply `cata` with a carrier of @b -> b@.
foldl :: (Listable f, Recursive t (f a)) => (b -> a -> b) -> b -> t -> b
foldl f =
flip
(cata (iter (\case
Neither -> id
Both a g -> g . flip f a)
. naturalList))