{-# LANGUAGE CPP
,MultiParamTypeClasses
,FunctionalDependencies
,FlexibleInstances #-}
module Data.ListLike.FoldableLL
(
FoldableLL(..),
fold, foldMap, foldM, sequence_, mapM_
) where
import Prelude hiding (foldl, foldr, foldr1, sequence_, mapM_, foldMap)
import qualified Data.Foldable as F
import Data.Monoid
import Data.Maybe
import qualified Data.List as L
class FoldableLL full item | full -> item where
foldl :: (a -> item -> a) -> a -> full -> a
foldl' :: (a -> item -> a) -> a -> full -> a
foldl' f a xs = foldr f' id xs a
where f' x k z = k $! f z x
foldl1 :: (item -> item -> item) -> full -> item
foldl1 f xs = fromMaybe (error "fold1: empty structure")
(foldl mf Nothing xs)
where mf Nothing y = Just y
mf (Just x) y = Just (f x y)
foldr :: (item -> b -> b) -> b -> full -> b
foldr' :: (item -> b -> b) -> b -> full -> b
foldr' f a xs = foldl f' id xs a
where f' k x z = k $! f x z
foldr1 :: (item -> item -> item) -> full -> item
foldr1 f xs = fromMaybe (error "foldr1: empty structure")
(foldr mf Nothing xs)
where mf x Nothing = Just x
mf x (Just y) = Just (f x y)
fold :: (FoldableLL full item, Monoid item) => full -> item
fold = foldMap id
foldMap :: (FoldableLL full item, Monoid m) => (item -> m) -> full -> m
foldMap f = foldr (mappend . f) mempty
instance FoldableLL [a] a where
foldl = L.foldl
foldl1 = L.foldl1
foldl' = L.foldl'
foldr = L.foldr
foldr1 = L.foldr1
foldr' = F.foldr'
foldM :: (Monad m, FoldableLL full item) => (a -> item -> m a) -> a -> full -> m a
foldM f z xs = foldr (\x rest a -> f a x >>= rest) return xs z
mapM_ :: (Monad m, FoldableLL full item) => (item -> m b) -> full -> m ()
mapM_ func = foldr ((>>) . func) (return ())
sequence_ :: (Monad m, FoldableLL full (m item)) => full -> m ()
sequence_ = mapM_ id