-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Miscellaneous utilities for pipes, required by glazier-tutorial
--   
--   Please see README.md
@package pipes-misc
@version 0.5.0.0

module Pipes.Misc.Concurrent

-- | Like Pipes.Concurrent.fromInput, but stays in STM. Using <tt>hoist
--   atomically</tt> to convert to IO monad seems to work. Do not use
--   <tt>unsafeHoist atomically</tt>. Each transaction is <a>atomically</a>
--   scoped around each yield, so be careful when <a>filter</a> or similar
--   pipes to remove yields as this results in larger transactions and it
--   may cause BlockIndefinitelyOnSTM exceptions. Intead, use Monoids to
--   yield mempty so that the STM state changes.
fromInputSTM :: Input a -> Producer' a STM ()

-- | Like Pipes.Concurrent.toOutput, but stays in STM. Using <tt>hoist
--   atomically</tt> to convert to IO monad seems to work. Do not use
--   <tt>unsafeHoist atomically</tt>.
toOutputSTM :: Output a -> Consumer' a STM ()

-- | Convert PC.Output <tt>a -&gt; STM Bool</tt> to <tt>a -&gt; MaybeT STM
--   ()</tt>
toOutputMaybeT :: Output a -> a -> MaybeT STM ()

-- | Converts a Producer in IO monad to a producer in STM monad.
mkProducerSTM :: Buffer a -> Producer a IO () -> IO (Producer a STM ())

-- | Converts a Producer in IO monad to a producer in STM monad. Also
--   returns the seal.
mkProducerSTM' :: Buffer a -> Producer a IO () -> IO (STM (), Producer a STM ())

-- | Reads as much as possible from an input and return a list of all
--   unblocked values read. Blocks if the first value read is blocked.
batch :: Input a -> Input (NonEmpty a)

-- | Combine a <a>Input</a> and a 'a -&gt; t STM b' into a <a>Producer</a>
--   of the result b. That is, given a input of messages, and something
--   that executes the messages to produce a result b, combine them to get
--   a Producer of the executed results.
execInput :: (MonadTrans t, Monad (t STM)) => Input a -> (a -> t STM b) -> Producer' b (t STM) ()

module Pipes.Misc.State.Lazy

-- | Store the output of the pipe into a MonadState.
store :: MonadState s m => Getter a b -> Setter' s b -> Pipe a a m r

-- | Yields a view into the stored value.
restore :: MonadState s m => Getter s b -> Pipe a (b, a) m r

-- | Yields a view into the stored value
restore' :: MonadState s m => Getter s b -> Pipe () b m r

-- | Do something with the state everytime there is a yield.
onState :: MonadState s m => (s -> m ()) -> Pipe a a m r

module Pipes.Misc.State.Strict

-- | Store the output of the pipe into a MonadState.
store :: MonadState s m => Getter a b -> Setter' s b -> Pipe a a m r

-- | Yields a view into the stored value.
restore :: MonadState s m => Getter s b -> Pipe a (b, a) m r

-- | Yields a view into the stored value
restore' :: MonadState s m => Getter s b -> Pipe () b m r

-- | Do something with the state everytime there is a yield.
onState :: MonadState s m => (s -> m ()) -> Pipe a a m r

module Pipes.Misc.Util

-- | Given a size and a initial tail, create a pipe that will buffer the
--   output of a producer. This pipe is stateful, and will only buffer
--   until the immediate connecting producer is finished.
--   
--   <pre>
--   forever $ do
--     a &lt;- await
--     yield a &gt;-&gt; buffer 2 [] -- will only ever result a producer of single 'a : []'.
--   </pre>
--   
--   <pre>
--   (forever $ do
--     a &lt;- await
--     yield a
--   ) &gt;-&gt; buffer 2 [] -- will buffer properly and produce '[latest, old]'
--   </pre>
buffer :: Monad m => Int -> [a] -> Pipe a [a] m r

-- | Run a pipe in a larger stream, using view function and modify function
--   of the larger stream.
locally :: Monad m => (s -> a) -> (b -> s -> t) -> Pipe a b m r -> Pipe s t m r

-- | Given comparison function and an initial value. yield the result of
--   comparing the value await with the previously awaited value.
compare :: Monad m => (a -> a -> b) -> a -> Pipe a b m r

-- | Given comparison function yield the result of comparing the value
--   await with the first awaited value.
compare' :: Monad m => (a -> a -> b) -> Pipe a b m r

-- | constantly yields the given value
always :: Monad m => a -> Producer a m r

-- | Makes the Producer return/pure the last value yielded, or the input
--   value if nothing was yielded
lastOr :: Monad m => a -> Producer a m () -> Producer a m a


-- | You can use the Arrow instance to get different types of ticker time.
--   Eg:
--   
--   <pre>
--   diffTimeEvery :: MonadIO io =&gt; C.Clock -&gt; Int -&gt; P.Producer' C.TimeSpec io r
--   diffTimeEvery clock micros = always () P.&gt;-&gt; delay micros P.&gt;-&gt; ticker clock P.&gt;-&gt; diffTime
--   
--   import Control.Arrow
--   import qualified Control.Category as Cat
--   import qualified Pipes.Shaft as PS
--   
--   diffAndTickEvery :: MonadIO io =&gt; C.Clock -&gt; Int -&gt; P.Producer' (C.TimeSpec, C.TimeSpec) io r
--   diffAndTickEvery clock micros = always () P.&gt;-&gt; delay micros P.&gt;-&gt; ticker clock P.&gt;-&gt;
--      PS.fromShaft (PS.Shaft diffTime &amp;&amp;&amp; Cat.id)
--   </pre>
module Pipes.Misc.Time

-- | Add a delay after every await
delay :: MonadIO io => Int -> Pipe a a io r

-- | After the first await, add a delay after every subsequent await.
delay' :: MonadIO io => Int -> Pipe a a io r

-- | obtain the threadDelay given a fps
fps :: Decimal -> Int

-- | Continuously yield the clock time Use with delay to reduce the yield
--   rate. Eg:
--   
--   <pre>
--   tickEvery :: MonadIO io =&gt; C.Clock -&gt; Int -&gt; P.Producer' C.TimeSpec io r
--   tickEvery clock micros = always () P.&gt;-&gt; delay micros P.&gt;-&gt; ticker clock
--   </pre>
ticker :: MonadIO io => Clock -> Pipe () TimeSpec io r

-- | Converts a stream of times, into a stream of delta time. The first
--   yield is zero.
diffTime :: Monad m => Pipe TimeSpec TimeSpec m r

-- | Converts a stream of epoch times into a stream of epoch time, where
--   zero is the first yielded time.
resetEpoch :: Monad m => Pipe TimeSpec TimeSpec m r

module Pipes.Misc
