{-| MonadPlus utilities. For instance, they can be applied with parsing libraries. -} module VectorBuilder.MonadPlus where import VectorBuilder.Prelude import Data.Vector (Vector) import qualified VectorBuilder.Builder as A import qualified VectorBuilder.Vector as B {-# INLINABLE many #-} many :: MonadPlus m => m a -> m (Vector a) many m = liftM B.build loop where loop = mplus (do !element <- m remainders <- loop return (A.singleton element <> remainders)) (return mempty) {-# INLINABLE sepBy #-} sepBy :: MonadPlus m => m element -> m separator -> m (Vector element) sepBy elementM separatorM = mplus (sepBy1 elementM separatorM) (return mempty) {-# INLINABLE sepBy1 #-} sepBy1 :: MonadPlus m => m element -> m separator -> m (Vector element) sepBy1 elementM separatorM = liftM B.build loop where loop = do !element <- elementM remainders <- mplus (separatorM >> loop) (return mempty) return (A.singleton element <> remainders)