module Text.XML.Enumerator.Combinators.General
(
chooseSplit
, permute
, permuteFallback
)
where
import Control.Monad (liftM)
chooseSplit :: (Monad m) => (a -> m (Maybe b)) -> [a] -> m (Maybe (b, [a]))
chooseSplit f xs = go xs []
where
go [] _ = return Nothing
go (i:is) is' = do
x <- f i
case x of
Nothing -> go is (i : is')
Just a -> return $ Just (a, is' ++ is)
permute :: (Monad m) => (a -> m (Maybe b)) -> [a] -> m (Maybe [b])
permute _ [] = return (Just [])
permute f is = do
x <- chooseSplit f is
case x of
Nothing -> return Nothing
Just (a, is') -> fmap (a:) `liftM` permute f is'
permuteFallback :: (Monad m) => m (Maybe [b]) -> (a -> m (Maybe b)) -> [a] -> m (Maybe [b])
permuteFallback _ _ [] = return (Just [])
permuteFallback fb f is = do
x <- chooseSplit f is
case x of
Nothing -> do y <- fb
case y of
Nothing -> return Nothing
Just as -> fmap (as ++) `liftM` permuteFallback fb f is
Just (a, is') -> fmap (a:) `liftM` permuteFallback fb f is'