-- |
-- Vector-specialised combinators often used for parsing.
module VectorExtras.Combinators where

import Data.Vector.Generic (Vector)
import VectorExtras.Accumulator (Accumulator)
import qualified VectorExtras.Accumulator as Acc
import VectorExtras.Combinators.Helpers
import VectorExtras.Prelude

many :: (MonadPlus m, Vector v a) => m a -> m (v a)
many :: m a -> m (v a)
many m a
getElement =
  Accumulator a -> m a -> m (Accumulator a)
forall (m :: * -> *) a.
MonadPlus m =>
Accumulator a -> m a -> m (Accumulator a)
accMany Accumulator a
forall a. Accumulator a
Acc.init m a
getElement m (Accumulator a) -> (Accumulator a -> v a) -> m (v a)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> Accumulator a -> v a
forall (v :: * -> *) a. Vector v a => Accumulator a -> v a
Acc.toVector

sepBy :: (MonadPlus m, Vector v a) => m a -> m b -> m (v a)
sepBy :: m a -> m b -> m (v a)
sepBy m a
getElement m b
getSeparator =
  do
    a
element <- m a
getElement
    Accumulator a -> v a
forall (v :: * -> *) a. Vector v a => Accumulator a -> v a
Acc.toVector (Accumulator a -> v a) -> m (Accumulator a) -> m (v a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Accumulator a -> m a -> m (Accumulator a)
forall (m :: * -> *) a.
MonadPlus m =>
Accumulator a -> m a -> m (Accumulator a)
accMany (a -> Accumulator a -> Accumulator a
forall a. a -> Accumulator a -> Accumulator a
Acc.add a
element Accumulator a
forall a. Accumulator a
Acc.init) (m b
getSeparator m b -> m a -> m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> m a
getElement)