    -- |
    -- MonadPlus utilities.
    -- For instance, they can be applied with parsing libraries.
    module VectorBuilder.MonadPlus where

    import qualified Data.Vector.Generic as C
    import qualified VectorBuilder.Builder as A
    import VectorBuilder.Prelude
    import qualified VectorBuilder.Vector as B

    {-# INLINEABLE many #-}
    many :: (MonadPlus m, C.Vector vector element) => m element -> m (vector element)
    many :: forall (m :: * -> *) (vector :: * -> *) element.
    (MonadPlus m, Vector vector element) =>
    m element -> m (vector element)
    many m element
    m =
      (Builder element -> vector element)
    -> m (Builder element) -> m (vector element)
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM Builder element -> vector element
    forall (vector :: * -> *) element.
    Vector vector element =>
    Builder element -> vector element
    B.build (m element -> m (Builder element)
    forall (m :: * -> *) element.
    MonadPlus m =>
    m element -> m (Builder element)
    manyBuilder m element
    m)

    {-# INLINEABLE manyBuilder #-}
    manyBuilder :: (MonadPlus m) => m element -> m (A.Builder element)
    manyBuilder :: forall (m :: * -> *) element.
    MonadPlus m =>
    m element -> m (Builder element)
    manyBuilder m element
    m =
      Builder element -> m (Builder element)
    loop Builder element
    forall a. Monoid a => a
    mempty
      where
        loop :: Builder element -> m (Builder element)
    loop !Builder element
    builder =
          m (Builder element) -> m (Builder element) -> m (Builder element)
    forall a. m a -> m a -> m a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    mplus
            ( do
                !element <- m element
    m
                loop (builder <> A.singleton element)
            )
            (Builder element -> m (Builder element)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Builder element
    builder)

    {-# INLINEABLE many1 #-}
    many1 :: (MonadPlus m, C.Vector vector element) => m element -> m (vector element)
    many1 :: forall (m :: * -> *) (vector :: * -> *) element.
    (MonadPlus m, Vector vector element) =>
    m element -> m (vector element)
    many1 m element
    m =
      do
        firstElement <- m element
    m
        builder <- manyBuilder m
        return (B.build (A.singleton firstElement <> builder))

    {-# INLINEABLE sepBy #-}
    sepBy :: (MonadPlus m, C.Vector vector element) => m element -> m separator -> m (vector element)
    sepBy :: forall (m :: * -> *) (vector :: * -> *) element separator.
    (MonadPlus m, Vector vector element) =>
    m element -> m separator -> m (vector element)
    sepBy m element
    elementM m separator
    separatorM =
      m (vector element) -> m (vector element) -> m (vector element)
    forall a. m a -> m a -> m a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    mplus (m element -> m separator -> m (vector element)
    forall (m :: * -> *) (vector :: * -> *) element separator.
    (MonadPlus m, Vector vector element) =>
    m element -> m separator -> m (vector element)
    sepBy1 m element
    elementM m separator
    separatorM) (vector element -> m (vector element)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return vector element
    forall (v :: * -> *) a. Vector v a => v a
    C.empty)

    {-# INLINEABLE sepBy1 #-}
    sepBy1 :: (MonadPlus m, C.Vector vector element) => m element -> m separator -> m (vector element)
    sepBy1 :: forall (m :: * -> *) (vector :: * -> *) element separator.
    (MonadPlus m, Vector vector element) =>
    m element -> m separator -> m (vector element)
    sepBy1 m element
    elementM m separator
    separatorM =
      do
        firstElement <- m element
    elementM
        builder <- loop (A.singleton firstElement)
        return (B.build builder)
      where
        loop :: Builder element -> m (Builder element)
    loop Builder element
    builder =
          m (Builder element) -> m (Builder element) -> m (Builder element)
    forall a. m a -> m a -> m a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    mplus
            ( do
                m separator
    separatorM
                !element <- m element
    elementM
                loop (builder <> A.singleton element)
            )
            (Builder element -> m (Builder element)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Builder element
    builder)