-- | This shows how 'Data.Foldable' is basically 'Recursive' specialized to -- lists. The true operation of 'Data.Foldable' is '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 `Foldable`, but designed to illustrate the -- representation of `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))