module Data.Drinkery.Combinators
( foldlFrom'
, foldMFrom
, traverseFrom_
, drainFrom
, lastFrom
)
where
import Control.Applicative
import Control.Monad hiding (foldM)
import qualified Data.Foldable as F
foldlFrom' :: (Foldable t, Monad m) => m (t a) -> (b -> a -> b) -> b -> m b
foldlFrom' m f = go where
go b = do
t <- m
if null t
then return b
else go $! F.foldl' f b t
foldMFrom :: (Foldable t, Monad m) => m (t a) -> (b -> a -> m b) -> b -> m b
foldMFrom m f = go where
go b = do
t <- m
if null t
then return b
else F.foldlM f b t >>= go
traverseFrom_ :: (Foldable t, Monad m) => m (t a) -> (a -> m b) -> m ()
traverseFrom_ m f = go where
go = do
t <- m
if null t then return () else F.traverse_ f t >> go
drainFrom :: (Foldable t, Monad m) => m (t a) -> m ()
drainFrom m = go where
go = m >>= \t -> unless (null t) go
lastFrom :: (Alternative t, Foldable t, Monad m) => m (t a) -> m (Maybe a)
lastFrom m = go empty where
go l = m >>= \t -> if null t
then return $! foldr (\x r _ -> r (Just x)) id l Nothing
else go t