module Data.Foldable.Extra
( module Data.Foldable
, sum'
, product'
, sumOn'
, productOn'
, anyM
, allM
, orM
, andM
, findM
, firstJustM
) where
import Data.Foldable
import qualified Control.Monad.Extra as MX
sum' :: (Foldable f, Num a) => f a -> a
sum' = foldl' (+) 0
product' :: (Foldable f, Num a) => f a -> a
product' = foldl' (*) 1
sumOn' :: (Foldable f, Num b) => (a -> b) -> f a -> b
sumOn' f = foldl' (\acc x -> acc + f x) 0
productOn' :: (Foldable f, Num b) => (a -> b) -> f a -> b
productOn' f = foldl' (\acc x -> acc * f x) 1
anyM :: (Foldable f, Monad m) => (a -> m Bool) -> f a -> m Bool
anyM p = foldr ((MX.||^) . p) (pure False)
allM :: (Foldable f, Monad m) => (a -> m Bool) -> f a -> m Bool
allM p = foldr ((MX.&&^) . p) (pure True)
orM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
orM = anyM id
andM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
andM = allM id
findM :: (Foldable f, Monad m) => (a -> m Bool) -> f a -> m (Maybe a)
findM p = foldr (\x -> MX.ifM (p x) (pure $ Just x)) (pure Nothing)
firstJustM :: (Foldable f, Monad m) => (a -> m (Maybe b)) -> f a -> m (Maybe b)
firstJustM p = MX.firstJustM p . toList