3-- Copyright : (c) 2017 Harendra Kumar
6-- Maintainer : harendra.kumar@gmail.com
7-- Stability : experimental
10-- The way a list represents a sequence of pure values, a stream represents a
11-- sequence of monadic actions. The monadic stream API offered by Streamly is
12-- very close to the Haskell "Prelude" pure lists' API, it can be considered as
13-- a natural extension of lists to monadic actions. Streamly streams provide
14-- concurrent composition and merging of streams. It can be considered as a
15-- concurrent list transformer. In contrast to the "Prelude" lists, merging or
16-- appending streams of arbitrary length is scalable and inexpensive.
18-- The basic stream type is 'Serial', it represents a sequence of IO actions,
19-- and is a 'Monad'. The type 'SerialT' is a monad transformer that can
20-- represent a sequence of actions in an arbitrary monad. The type 'Serial' is
21-- in fact a synonym for @SerialT IO@. There are a few more types similar to
22-- 'SerialT', all of them represent a stream and differ only in the
23-- 'Semigroup', 'Applicative' and 'Monad' compositions of the stream. 'Serial'
24-- and 'WSerial' types compose serially whereas 'Async' and 'WAsync'
25-- types compose concurrently. All these types can be freely inter-converted
26-- using type combinators without any cost. You can freely switch to any type
27-- of composition at any point in the program. When no type annotation or
28-- explicit stream type combinators are used, the default stream type is
29-- inferred as 'Serial'.
31-- Here is a simple console echo program example:
34-- > runStream $ S.repeatM getLine & S.mapM putStrLn
37-- For more details please see the "Streamly.Tutorial" module and the examples
38-- directory in this package.
40-- This module exports stream types, instances and some basic operations.
41-- Functionality exported by this module include:
43-- * Semigroup append ('<>') instances as well as explicit operations for merging streams
44-- * Monad and Applicative instances for looping over streams
45-- * Zip Applicatives for zipping streams
46-- * Stream type combinators to convert between different composition styles
47-- * Some basic utilities to run and fold streams
49-- See the "Streamly.Prelude" module for comprehensive APIs for construction,
50-- generation, elimination and transformation of streams.
52-- This module is designed to be imported unqualified:
60#if __GLASGOW_HASKELL__ >= 800
61{-# OPTIONS_GHC -Wno-orphans #-}
64#include "Streamly/Streams/inline.h"
70 -- * Stream transformers
76 -- ** Concurrent Lookahead Streams
80 -- ** Concurrent Asynchronous Streams
94 -- * Parallel Function Application
111 -- * Concurrency Control
116 -- * Folding Containers of Streams
122 -- * Stream Type Adapters
168import Streamly.Streams.StreamK hiding (runStream, serial)
169import Streamly.Streams.Serial
170import Streamly.Streams.Async
171import Streamly.Streams.Ahead
172import Streamly.Streams.Parallel
173import Streamly.Streams.Zip
174import Streamly.Streams.Prelude
175import Streamly.Streams.SVar (maxThreads, maxBuffer)
176import Streamly.SVar (MonadAsync)
177import Data.Semigroup (Semigroup(..))
179import qualified Streamly.Streams.StreamD as D
180import qualified Streamly.Streams.StreamK as K
182-- XXX This should perhaps be moved to Prelude.
184------------------------------------------------------------------------------
185-- Eliminating a stream
186------------------------------------------------------------------------------
188-- | Run a streaming composition, discard the results. By default it interprets
189-- the stream as 'SerialT', to run other types of streams use the type adapting
190-- combinators for example @runStream . 'asyncly'@.
193{-# INLINE_EARLY runStream #-}
194runStream :: Monad m => SerialT m a -> m ()
195runStream m = D.runStream $ D.fromStreamK (toStream m)
196{-# RULES "runStream fallback to CPS" [1]
197 forall a. D.runStream (D.fromStreamK a) = K.runStream a #-}
199-- | Same as 'runStream'
202{-# DEPRECATED runStreaming "Please use runStream instead." #-}
203runStreaming :: (Monad m, IsStream t) => t m a -> m ()
204runStreaming = runStream . K.adapt
206-- | Same as @runStream@.
209{-# DEPRECATED runStreamT "Please use runStream instead." #-}
210runStreamT :: Monad m => SerialT m a -> m ()
211runStreamT = runStream
213-- | Same as @runStream . wSerially@.
216{-# DEPRECATED runInterleavedT "Please use 'runStream . interleaving' instead." #-}
217runInterleavedT :: Monad m => WSerialT m a -> m ()
218runInterleavedT = runStream . K.adapt
220-- | Same as @runStream . parallely@.
223{-# DEPRECATED runParallelT "Please use 'runStream . parallely' instead." #-}
224runParallelT :: Monad m => ParallelT m a -> m ()
225runParallelT = runStream . K.adapt
227-- | Same as @runStream . asyncly@.
230{-# DEPRECATED runAsyncT "Please use 'runStream . asyncly' instead." #-}
231runAsyncT :: Monad m => AsyncT m a -> m ()
232runAsyncT = runStream . K.adapt
234-- | Same as @runStream . zipping@.
237{-# DEPRECATED runZipStream "Please use 'runStream . zipSerially instead." #-}
238runZipStream :: Monad m => ZipSerialM m a -> m ()
239runZipStream = runStream . K.adapt
241-- | Same as @runStream . zippingAsync@.
244{-# DEPRECATED runZipAsync "Please use 'runStream . zipAsyncly instead." #-}
245runZipAsync :: Monad m => ZipAsyncM m a -> m ()
246runZipAsync = runStream . K.adapt
248------------------------------------------------------------------------------
250------------------------------------------------------------------------------
254-- Serial streams compose serially or non-concurrently. In a composed stream,
255-- each action is executed only after the previous action has finished. The two
256-- serial stream types 'SerialT' and 'WSerialT' differ in how they traverse the
257-- streams in a 'Semigroup' or 'Monad' composition.
261-- The async style streams execute actions asynchronously and consume the
262-- outputs as well asynchronously. In a composed stream, at any point of time
263-- more than one stream can run concurrently and yield elements. The elements
264-- are yielded by the composed stream as they are generated by the constituent
265-- streams on a first come first serve basis. Therefore, on each run the
266-- stream may yield elements in a different sequence depending on the delays
267-- introduced by scheduling. The two async types 'AsyncT' and 'WAsyncT' differ
268-- in how they traverse streams in 'Semigroup' or 'Monad' compositions.
272-- 'ZipSerialM' and 'ZipAsyncM', provide 'Applicative' instances for zipping the
273-- corresponding elements of two streams together. Note that these types are
278-- Stream processing functions can be composed in a chain using function
279-- application with or without the '$' operator, or with reverse function
280-- application operator '&'. Streamly provides concurrent versions of these
281-- operators applying stream processing functions such that each stage of the
282-- stream can run in parallel. The operators start with a @|@; we can read '|$'
283-- as "@parallel dollar@" to remember that @|@ comes before '$'.
285-- Imports for the code snippets below:
289-- import qualified Streamly.Prelude as S
290-- import Control.Concurrent
294-- The 'Semigroup' operation '<>' of each stream type combines two streams in a
295-- type specific manner. This section provides polymorphic versions of '<>'
296-- which can be used to combine two streams in a predetermined way irrespective
301-- These combinators can be used at any point in a stream composition to
302-- control the concurrency of the enclosed stream. When the combinators are
303-- used in a nested manner, the nearest enclosing combinator overrides the
304-- outer ones. These combinators have no effect on 'Parallel' streams,
305-- concurrency for 'Parallel' streams is always unbounded.
306-- Note that the use of these combinators does not enable concurrency, to
307-- enable concurrency you have to use one of the concurrent stream type
312-- You may want to use different stream composition styles at different points
313-- in your program. Stream types can be freely converted or adapted from one
314-- type to another. The 'IsStream' type class facilitates type conversion of
315-- one stream type to another. It is not used directly, instead the type
316-- combinators provided below are used for conversions.
318-- To adapt from one monomorphic type (e.g. 'AsyncT') to another monomorphic
319-- type (e.g. 'SerialT') use the 'adapt' combinator. To give a polymorphic code
320-- a specific interpretation or to adapt a specific type to a polymorphic type
321-- use the type specific combinators e.g. 'asyncly' or 'wSerially'. You
322-- cannot adapt polymorphic code to polymorphic code, as the compiler would not know
323-- which specific type you are converting from or to. If you see a an
324-- @ambiguous type variable@ error then most likely you are using 'adapt'
325-- unnecessarily on polymorphic code.
330-- These are variants of standard 'Foldable' fold functions that use a
331-- polymorphic stream sum operation (e.g. 'async' or 'wSerial') to fold a
332-- container of streams.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list