data Folder a b c = Folder -- o procesare pe liste { foldNull :: c, -- rezultat pentru lista vidă foldCons :: a -> b -> c -- rezultat care asamblează o valoare din listă a cu un acumulator de tip b } fold :: Foldable t => Folder a b b -> t a -> b fold folder = foldr (foldCons folder) (foldNull folder) -- folder :: Folder sumFolder :: Num a => Folder a a a sumFolder = Folder 0 (+) sumList :: (Foldable t, Num a) => t a -> a sumList = fold sumFolder -- sumList [1..10] --lengthFolder = Folder 0 (\x acc -> acc + 1) lengthFolder = Folder 0 (const (+1)) len :: Foldable t => t a -> Integer len = fold lengthFolder -- len [1..10] (<+>) :: Folder a b b -> Folder a c c -> Folder a (b, c) (b, c) f <+> g = Folder (foldNull f, foldNull g) (\x (accF, accG) -> (foldCons f x accF, foldCons g x accG)) sumLength :: (Foldable t, Num a) => t a -> (a, Integer) sumLength = fold (sumFolder <+> lengthFolder) -- sumLength [1..10]