{-# LANGUAGE Trustworthy #-}
module Data.Foldable (
Foldable(..),
foldrM,
foldlM,
traverse_,
for_,
sequenceA_,
asum,
mapM_,
forM_,
sequence_,
msum,
toList,
concat,
concatMap,
and,
or,
any,
all,
sum,
product,
maximum,
maximumBy,
minimum,
minimumBy,
elem,
notElem,
find
) where
import Prelude hiding (foldl, foldr, foldl1, foldr1, mapM_, sequence_,
elem, notElem, concat, concatMap, and, or, any, all,
sum, product, maximum, minimum)
import qualified Prelude (foldl, foldr, foldl1, foldr1)
import qualified Data.List as List (foldl')
import Control.Applicative
import Control.Monad (MonadPlus(..))
import Data.Maybe (fromMaybe, listToMaybe)
import Data.Monoid
import Data.Proxy
import GHC.Exts (build)
import GHC.Arr
class Foldable t where
fold :: Monoid m => t m -> m
fold = foldMap id
foldMap :: Monoid m => (a -> m) -> t a -> m
foldMap f = foldr (mappend . f) mempty
foldr :: (a -> b -> b) -> b -> t a -> b
foldr f z t = appEndo (foldMap (Endo . f) t) z
foldr' :: (a -> b -> b) -> b -> t a -> b
foldr' f z0 xs = foldl f' id xs z0
where f' k x z = k $! f x z
foldl :: (b -> a -> b) -> b -> t a -> b
foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
foldl' :: (b -> a -> b) -> b -> t a -> b
foldl' f z0 xs = foldr f' id xs z0
where f' x k z = k $! f z x
foldr1 :: (a -> a -> a) -> t a -> a
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)
foldl1 :: (a -> a -> a) -> t a -> a
foldl1 f xs = fromMaybe (error "foldl1: empty structure")
(foldl mf Nothing xs)
where
mf Nothing y = Just y
mf (Just x) y = Just (f x y)
instance Foldable Maybe where
foldr _ z Nothing = z
foldr f z (Just x) = f x z
foldl _ z Nothing = z
foldl f z (Just x) = f z x
instance Foldable [] where
foldr = Prelude.foldr
foldl = Prelude.foldl
foldl' = List.foldl'
foldr1 = Prelude.foldr1
foldl1 = Prelude.foldl1
instance Foldable (Either a) where
foldMap _ (Left _) = mempty
foldMap f (Right y) = f y
foldr _ z (Left _) = z
foldr f z (Right y) = f y z
instance Foldable ((,) a) where
foldMap f (_, y) = f y
foldr f z (_, y) = f y z
instance Ix i => Foldable (Array i) where
foldr f z = Prelude.foldr f z . elems
foldl f z = Prelude.foldl f z . elems
foldr1 f = Prelude.foldr1 f . elems
foldl1 f = Prelude.foldl1 f . elems
instance Foldable Proxy where
foldMap _ _ = mempty
{-# INLINE foldMap #-}
fold _ = mempty
{-# INLINE fold #-}
foldr _ z _ = z
{-# INLINE foldr #-}
foldl _ z _ = z
{-# INLINE foldl #-}
foldl1 _ _ = error "foldl1: Proxy"
{-# INLINE foldl1 #-}
foldr1 _ _ = error "foldr1: Proxy"
{-# INLINE foldr1 #-}
instance Foldable (Const m) where
foldMap _ _ = mempty
foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b
foldrM f z0 xs = foldl f' return xs z0
where f' k x z = f x z >>= k
foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
foldlM f z0 xs = foldr f' return xs z0
where f' x k z = f z x >>= k
traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
traverse_ f = foldr ((*>) . f) (pure ())
for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f ()
{-# INLINE for_ #-}
for_ = flip traverse_
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
mapM_ f = foldr ((>>) . f) (return ())
forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m ()
{-# INLINE forM_ #-}
forM_ = flip mapM_
sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f ()
sequenceA_ = foldr (*>) (pure ())
sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
sequence_ = foldr (>>) (return ())
asum :: (Foldable t, Alternative f) => t (f a) -> f a
{-# INLINE asum #-}
asum = foldr (<|>) empty
msum :: (Foldable t, MonadPlus m) => t (m a) -> m a
{-# INLINE msum #-}
msum = foldr mplus mzero
toList :: Foldable t => t a -> [a]
{-# INLINE toList #-}
toList t = build (\ c n -> foldr c n t)
concat :: Foldable t => t [a] -> [a]
concat = fold
concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
concatMap = foldMap
and :: Foldable t => t Bool -> Bool
and = getAll . foldMap All
or :: Foldable t => t Bool -> Bool
or = getAny . foldMap Any
any :: Foldable t => (a -> Bool) -> t a -> Bool
any p = getAny . foldMap (Any . p)
all :: Foldable t => (a -> Bool) -> t a -> Bool
all p = getAll . foldMap (All . p)
sum :: (Foldable t, Num a) => t a -> a
sum = getSum . foldMap Sum
product :: (Foldable t, Num a) => t a -> a
product = getProduct . foldMap Product
maximum :: (Foldable t, Ord a) => t a -> a
maximum = foldr1 max
maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
maximumBy cmp = foldr1 max'
where max' x y = case cmp x y of
GT -> x
_ -> y
minimum :: (Foldable t, Ord a) => t a -> a
minimum = foldr1 min
minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
minimumBy cmp = foldr1 min'
where min' x y = case cmp x y of
GT -> y
_ -> x
elem :: (Foldable t, Eq a) => a -> t a -> Bool
elem = any . (==)
notElem :: (Foldable t, Eq a) => a -> t a -> Bool
notElem x = not . elem x
find :: Foldable t => (a -> Bool) -> t a -> Maybe a
find p = listToMaybe . concatMap (\ x -> if p x then [x] else [])