1 module Hcompta.Lib.Foldable where
 
   4 import Data.Maybe (listToMaybe, maybeToList)
 
   5 import Data.Foldable (Foldable, foldMap, foldr)
 
   7 -- | Return the first non-'Nothing' returned by the given function
 
   8 --   applied on the elements of a 'Foldable'.
 
   9 find :: Foldable t => (a -> Maybe b) -> t a -> Maybe b
 
  10 find f = listToMaybe . Data.Foldable.foldMap (maybeToList . f)
 
  12 -- | Like 'Data.Either.partitionEithers' but generalized
 
  13 --   to work on a 'Foldable' containing 'Monoid's.
 
  15 -- NOTE: any lazyness on resulting 'Monoid's is preserved.
 
  17  :: (Foldable t, Monoid r, Monoid l)
 
  18  => t (Either l r) -> (l, r)
 
  20         Data.Foldable.foldr (either left right) (mempty, mempty) m
 
  22                 left  a ~(l, r) = (a`mappend`l, r)
 
  23                 right a ~(l, r) = (l, a`mappend`r)
 
  25 -- | Return a tuple of accumulated 'Left's and folded 'Right's
 
  26 --   in the given 'Foldable'.
 
  28 --   * NOTE: any lazyness on resulting 'Monoid's is preserved.
 
  29 --   * WARNING: beware that given an infinite 'Foldable',
 
  30 --              the initial 'Right' accumulator will never be appended
 
  31 --              to the final 'Right' accumulator.
 
  32 accumLeftsAndFoldrRights
 
  33  :: (Foldable t, Monoid l)
 
  34  => (r -> ra -> ra) -> ra -> t (Either l r) -> (l, ra)
 
  35 accumLeftsAndFoldrRights f rempty m =
 
  36         Data.Foldable.foldr (either left right) (mempty, rempty) m
 
  38                 left  a ~(l, r) = (a`mappend`l, r)
 
  39                 right a ~(l, r) = (l, f a r)