on master help sign in
Update the docs of AheadT for brevity/clarity
1f1e3bdHarendra Kumar
src/Streamly/Internal/Data/Stream/Ahead.hs+41−36
@@ -595,8 +595,16 @@ forkSVarAhead m1 m2 = mkStream $ \st yld sng stp -> do
595
595
596infixr 6 `ahead`
596infixr 6 `ahead`
597
597
598−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'AheadT'.
598+-- | Appends two streams, some future actions may be evaluated concurrently,
599−-- Merges two streams sequentially but with concurrent lookahead.
599+-- ahead of time. The behavior is similar to 'consM' for 'AheadT' streams:
600+--
601+-- >>> stream = Stream.yieldM (delay 2) `ahead` Stream.yieldM (delay 1)
602+-- >>> Stream.toList stream -- IO [Int]
603+-- 1 sec
604+-- 2 sec
605+-- [2,1]
606+--
607+-- This operation can be used to fold an infinite lazy container of streams.
600--
608--
601-- /Since: 0.3.0 ("Streamly")/
609-- /Since: 0.3.0 ("Streamly")/
602--
610--
@@ -625,46 +633,43 @@ consMAhead m r = fromStream $ K.yieldM m `ahead` (toStream r)
625-- AheadT
633-- AheadT
626------------------------------------------------------------------------------
634------------------------------------------------------------------------------
627
635
628−-- | The 'Semigroup' operation for 'AheadT' appends two streams. The combined
636+-- | For 'AheadT' streams:
629−-- stream behaves like a single stream with the actions from the second stream
630−-- appended to the first stream. The combined stream is evaluated in the
631−-- speculative style. This operation can be used to fold an infinite lazy
632−-- container of streams.
633--
637--
634-- @
638-- @
635−-- import "Streamly.Prelude"
639+-- (<>) = 'Streamly.Prelude.ahead'
636−-- import qualified "Streamly.Prelude" as S
640+-- (>>=) = flip . 'Streamly.Prelude.concatMapWith' 'Streamly.Prelude.ahead'
637−-- import Control.Concurrent
638−--
639−-- main = do
640−-- xs \<- S.'toList' . S.'aheadly' $ (p 1 |: p 2 |: nil) <> (p 3 |: p 4 |: nil)
641−-- print xs
642−-- where p n = threadDelay 1000000 >> return n
643−-- @
644−-- @
645−-- [1,2,3,4]
646-- @
641-- @
647--
642--
648−-- Any exceptions generated by a constituent stream are propagated to the
643+-- Any exceptions generated by concurrent evaluation are propagated to the
649−-- output stream.
644+-- output stream as soon as they occur.
650--
645--
651−-- The monad instance of 'AheadT' may run each monadic continuation (bind)
646+-- A single 'Monad' bind behaves like a @for@ loop with iterations executed
652−-- concurrently in a speculative manner, performing side effects in a partially
647+-- concurrently, ahead of time, producing side effects of iterations out of
653−-- ordered manner but producing the outputs in an ordered manner like
648+-- order, but results in order:
654−-- 'SerialT'.
655--
649--
656−-- @
650+-- >>> :{
657−-- main = S.drain . S.'aheadly' $ do
651+-- Stream.toList $ Stream.aheadly $ do
658−-- n <- return 3 \<\> return 2 \<\> return 1
652+-- x <- Stream.fromList [2,1] -- foreach x in stream
659−-- S.yieldM $ do
653+-- Stream.yieldM $ delay x
660−-- threadDelay (n * 1000000)
654+-- :}
661−-- myThreadId >>= \\tid -> putStrLn (show tid ++ ": Delay " ++ show n)
655+-- 1 sec
662−-- @
656+-- 2 sec
657+-- [2,1]
658+--
659+-- Nested monad binds behave like nested @for@ loops with nested iterations
660+-- executed concurrently, ahead of time:
661+--
663−-- @
662+-- >>> :{
664−-- ThreadId 40: Delay 1
663+-- Stream.toList $ Stream.aheadly $ do
665−-- ThreadId 39: Delay 2
664+-- x <- Stream.fromList [1,2] -- foreach x in stream
666−-- ThreadId 38: Delay 3
665+-- y <- Stream.fromList [2,4] -- foreach y in stream
667−-- @
666+-- Stream.yieldM $ delay (x + y)
667+-- :}
668+-- 3 sec
669+-- 4 sec
670+-- 5 sec
671+-- 6 sec
672+-- [3,5,4,6]
668--
673--
669-- /Since: 0.3.0 ("Streamly")/
674-- /Since: 0.3.0 ("Streamly")/
670--
675--
src/Streamly/Prelude.hs+9−27
@@ -907,33 +907,15 @@ import Streamly.Internal.Data.Stream.IsStream
907
907
908-- $ahead
908-- $ahead
909--
909--
910−-- When a stream consumer demands an element from a speculative stream
910+-- Speculative streams evaluate some future actions speculatively and
911−-- constructed as @a \`consM` b \`consM` ... nil@, the action @a@ at the head
911+-- concurrently, and keep the results ready for consumption. As in serial
912−-- of the stream is executed and the output of the action is supplied to the
912+-- streams, results are consumed in the same order as the actions in the
913−-- consumer. However, in addition to the action at the head multiple actions
913+-- stream.
914−-- following it may also be executed concurrently and the results buffered.
915−-- When the next element is demanded it may be served from the buffer and we
916−-- may execute the next action in the sequence to keep the buffer adequately
917−-- filled. Thus, the actions are executed concurrently but results consumed in
918−-- serial order just like serial streams. `consM` can be used to fold an
919−-- infinite lazy container of effects, as the number of concurrent executions
920−-- is limited.
921−--
922−-- Similar to 'consM', the monadic stream generation (e.g. replicateM) and
923−-- transformation operations (e.g. mapM) on speculative streams can execute
924−-- multiple effects concurrently in a speculative manner.
925−--
926−-- How many effects can be executed concurrently and how many results can be
927−-- buffered are controlled by 'maxThreads' and 'maxBuffer' combinators
928−-- respectively. The actual number of concurrent threads is adjusted according
929−-- to the rate at which the consumer is consuming the stream. It may even
930−-- execute actions serially in a single thread if that is enough to match the
931−-- consumer's speed.
932−--
914+--
933−-- Speculative streams enforce ordering of the results of actions in the stream
915+-- Even though the results of actions are ordered, the side effects are only
934−-- but the side effects are only partially ordered. Therefore, the semigroup
916+-- partially ordered. Therefore, the semigroup operation is not commutative
935−-- operation for speculative streams is not commutative from the pure outputs
936−-- perspective but commutative from side effects perspective.
917+-- from the pure outputs perspective but commutative from side effects
918+-- perspective.
937
919
938-- $async
920-- $async
939--
921--