{- | An effect allowing writes to an accumulated quantity alongside a computed value, and reads from the accumulator. An 'Accum' @w@ effect keeps track of a monoidal datum of type @w@ and strictly appends to that monoidal value with the 'add' effect. Previous writes to that value can be read with the 'look' effect. Predefined carriers: * "Control.Carrier.Accum.Church" * "Control.Carrier.Accum.Strict". (A lazy carrier is not provided due to the inherent space leaks associated with lazy accumulation monads, similar to lazy writer monads.) * "Control.Monad.Trans.Accum" If 'Accum' @w@ is the last effect in a stack, it can be interpreted to a function @w -> (w, a)@ given some result type @a@ and the presence of a 'Monoid' instance for @w@. -- | @since 1.1.2.0 -} module Control.Effect.Accum ( -- * Accumulation effect Accum(..) , add , look , looks -- * Re-exports , Algebra , Has , run ) where import Control.Algebra import Control.Effect.Accum.Internal (Accum(..)) -- | Write a value to the log. -- -- @ -- 'runAccum' w0 ('add' w '>>' m) = 'Data.Bifunctor.first' ('mappend' w) '<$>' 'runAccum' w0 m -- 'runAccum' w0 ('add' w '>>' m) = runAccum (w0 <> w) m -- @ -- -- @since 1.1.2.0 add :: Has (Accum w) sig m => w -> m () add :: w -> m () add w w = Accum w m () -> m () forall (eff :: (* -> *) -> * -> *) (sig :: (* -> *) -> * -> *) (m :: * -> *) a. (Member eff sig, Algebra sig m) => eff m a -> m a send (w -> Accum w m () forall w (m :: * -> *). w -> Accum w m () Add w w) {-# INLINE add #-} -- | Look up the previous accumulation -- -- @ -- 'runAccum' w 'look' = 'return' (w, w) -- 'runAccum' w ('look' >>= continuation) = 'runAccum' w (continuation w) -- @ -- -- @since 1.1.2.0 look :: Has (Accum w) sig m => m w look :: m w look = Accum w m w -> m w forall (eff :: (* -> *) -> * -> *) (sig :: (* -> *) -> * -> *) (m :: * -> *) a. (Member eff sig, Algebra sig m) => eff m a -> m a send Accum w m w forall w (m :: * -> *). Accum w m w Look {-# INLINE look #-} -- | Look up the previous accumulation and apply a function to it. -- -- @ -- looks f = fmap f look -- @ -- -- @since 1.1.2.0 looks :: Has (Accum w) sig m => (w -> a) -> m a looks :: (w -> a) -> m a looks w -> a f = (w -> a) -> m w -> m a forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap w -> a f m w forall w (sig :: (* -> *) -> * -> *) (m :: * -> *). Has (Accum w) sig m => m w look {-# INLINE looks #-}