module VectorExtras.Combinators.Helpers where

import VectorExtras.Accumulator (Accumulator)
import qualified VectorExtras.Accumulator as Acc
import VectorExtras.Prelude

-- * General

orPure :: (Alternative m) => a -> m a -> m a
orPure :: forall (m :: * -> *) a. Alternative m => a -> m a -> m a
orPure a
res m a
main =
  m a
main forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure a
res

-- * Accumulator-oriented

accMany :: (MonadPlus m) => Accumulator a -> m a -> m (Accumulator a)
accMany :: forall (m :: * -> *) a.
MonadPlus m =>
Accumulator a -> m a -> m (Accumulator a)
accMany Accumulator a
acc m a
getElement =
  Accumulator a -> m (Accumulator a)
collect Accumulator a
acc
  where
    collect :: Accumulator a -> m (Accumulator a)
collect !Accumulator a
acc =
      forall (m :: * -> *) a. Alternative m => a -> m a -> m a
orPure Accumulator a
acc forall a b. (a -> b) -> a -> b
$ m a
getElement forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Accumulator a -> m (Accumulator a)
collect forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. a -> Accumulator a -> Accumulator a
Acc.add Accumulator a
acc