{-| 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 import qualified Data.Vector.Generic as C {-# INLINABLE many #-} many :: (MonadPlus m, C.Vector vector element) => m element -> m (vector element) 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, C.Vector vector element) => m element -> m separator -> m (vector element) sepBy elementM separatorM = mplus (sepBy1 elementM separatorM) (return C.empty) {-# INLINABLE sepBy1 #-} sepBy1 :: (MonadPlus m, C.Vector vector element) => 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)