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 :: a -> m a -> m a
orPure a
res m a
main =
  m a
main m a -> m a -> m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> a -> m 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 :: 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 =
      Accumulator a -> m (Accumulator a) -> m (Accumulator a)
forall (m :: * -> *) a. Alternative m => a -> m a -> m a
orPure Accumulator a
acc (m (Accumulator a) -> m (Accumulator a))
-> m (Accumulator a) -> m (Accumulator a)
forall a b. (a -> b) -> a -> b
$ m a
getElement m a -> (a -> m (Accumulator a)) -> m (Accumulator a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Accumulator a -> m (Accumulator a)
collect (Accumulator a -> m (Accumulator a))
-> (a -> Accumulator a) -> a -> m (Accumulator a)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a -> Accumulator a -> Accumulator a)
-> Accumulator a -> a -> Accumulator a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> Accumulator a -> Accumulator a
forall a. a -> Accumulator a -> Accumulator a
Acc.add Accumulator a
acc