on d2c4df4 help sign in
streamly/src/Streamly.hs
228 lines 8.6 kB history raw
1-- |
2-- Module : Streamly
3-- Copyright : (c) 2017 Harendra Kumar
4--
5-- License : BSD3
6-- Maintainer : harendra.kumar@gmail.com
7-- Stability : experimental
8-- Portability : GHC
10module Streamly
11 (
12 -- * Background
13 -- $background
15 -- * Overview
16 -- $overview
18 MonadParallel
19 , IsStream
21 -- * Serial Streams
22 -- $serial
23 , SerialT
24 , CoserialT
26 -- * Parallel Streams
27 -- $parallel
28 , CoparallelT
29 , ParallelT
31 -- * Zipping Streams
32 -- $zipping
33 , ZipSerial
34 , ZipParallel
36 -- * Stream Type Adapters
37 -- $adapters
38 , serially
39 , coserially
40 , coparallely
41 , parallely
42 , zipSerially
43 , zipParallely
44 , adapt
46 -- * Running Streams
47 , runStream
49 -- * Transformation
50 , async
52 -- * Polymorphic Sum Operations
53 -- $sum
54 , serial
55 , coserial
56 , coparallel
57 , parallel
59 -- * Polymorphic Fold Utilities
60 -- $foldutils
61 , foldWith
62 , foldMapWith
63 , forEachWith
65 -- * Re-exports
66 , Monoid (..)
67 , Semigroup (..)
68 , Alternative (..)
69 , MonadPlus (..)
70 , MonadIO (..)
71 , MonadTrans (..)
73 -- * Deprecated
74 , MonadAsync
75 , Streaming
76 , runStreaming
77 , runStreamT
78 , runInterleavedT
79 , runParallelT
80 , runZipAsync
81 , runAsyncT
82 , runZipStream
83 , StreamT
84 , InterleavedT
85 , AsyncT
86 , ZipStream
87 , ZipAsync
88 , interleaving
89 , asyncly
90 , zipping
91 , zippingAsync
92 , (<=>)
93 , (<|)
94 )
95where
97import Streamly.Streams
98import Data.Semigroup (Semigroup(..))
99import Control.Applicative (Alternative(..))
100import Control.Monad (MonadPlus(..))
101import Control.Monad.IO.Class (MonadIO (..))
102import Control.Monad.Trans.Class (MonadTrans (..))
104-- $background
105--
106-- Streamly provides a monad transformer that extends the product style
107-- composition of monads to streams of many elements of the same type; it is a
108-- functional programming equivalent of nested loops from imperative
109-- programming. Composing each element in one stream with each element in the
110-- other stream generalizes the monadic product of single elements. You can
111-- think of the IO monad as a special case of the more general @SerialT IO@
112-- monad; with single element streams. List transformers and logic programming
113-- monads also provide a similar product style composition of streams, however
114-- streamly generalizes it with the time dimension; allowing streams to be
115-- composed in an asynchronous and concurrent fashion in many different ways.
116-- It also provides multiple alternative ways of composing streams e.g.
117-- serial, interleaved or concurrent.
118--
119-- The seemingly simple addition of asynchronicity and concurrency to product
120-- style streaming composition unifies a number of disparate abstractions into
121-- one powerful and elegant abstraction. A wide variety of programming
122-- problems can be solved elegantly with this abstraction. In particular, it
123-- unifies three major programming domains namely non-deterministic (logic)
124-- programming, concurrent programming and functional reactive programming. In
125-- other words, you can do everything with this one abstraction that you could
126-- with list transformers (e.g.
127-- <https://hackage.haskell.org/package/list-t list-t>), logic programming
128-- monads (e.g. <https://hackage.haskell.org/package/logict logict>),
129-- streaming libraries (a lot of what
130-- <https://hackage.haskell.org/package/conduit conduit> or
131-- <https://hackage.haskell.org/package/pipes pipes> can do), concurrency
132-- libraries (e.g. <https://hackage.haskell.org/package/async async>) and FRP
133-- libraries (e.g. <https://hackage.haskell.org/package/Yampa Yampa> or
134-- <https://hackage.haskell.org/package/reflex reflex>).
136-- $overview
137--
138-- Streamly provides six distinct stream types i.e. 'SerialT', 'CoserialT',
139-- 'CoparallelT' and 'ParallelT', 'ZipSerial' and 'ZipParallel', each representing a
140-- stream of elements. All these types have the same underlying representation
141-- and can be adapted from one to another using type adaptor combinators
142-- described later. Each of these types belongs to the 'IsStream' type class
143-- which helps converting the specific type to and from the underlying generic
144-- stream type.
145--
146-- The types 'SerialT', 'CoserialT', 'CoparallelT' and 'ParallelT' are 'Monad'
147-- transformers with the monadic bind operation combining streams in a product
148-- style in much the same way as a list monad or a list transformer i.e. each
149-- element from one stream is combined with every element of the other stream.
150-- However, the applicative and monadic composition of these types differ in
151-- terms of the ordering and time sequence in which the elements from two
152-- streams are combined. 'SerialT' and 'CoserialT' compose streams serially
153-- whereas 'CoparallelT' and 'ParallelT' are their concurrent counterparts. See the
154-- documentation of the respective types for more details.
155--
156-- The types 'ZipSerial' and 'ZipParallel' provide 'Applicative' instances to zip
157-- two streams together i.e. each element in one stream is combined with the
158-- corresponding element in the other stream. 'ZipSerial' generates the streams
159-- being zipped serially whereas 'ZipParallel' produces both the elements being
160-- zipped concurrently.
161--
162-- Two streams of the same type can be merged using a sum style composition to
163-- generate a stream of the same type where the output stream would contain all
164-- elements of both the streams. However, the sequence or the manner
165-- (concurrent or serial) in which the elements in the resulting stream are
166-- produced depends on the type of the stream.
167--
168-- For more details please see the "Streamly.Tutorial" and "Streamly.Examples"
169-- (the latter is available only when built with the 'examples' build flag).
171-- A simple inline example here illustrating applicative, monad and alternative
172-- compositions.
174-- $serial
175--
176-- Serial streams compose serially or non-concurrently. In a composed stream,
177-- at any point of time only one constituent stream runs and yields an element.
178-- The two serial stream types 'SerialT' and 'CoserialT' differ in how they
179-- merge streams together in a 'Semigroup' or 'Monad' composition. As these
180-- streams are serial, the sequence of items in a composed stream can be solely
181-- determined by the position of elements in the consituent streams.
183-- $parallel
184--
185-- Parallel streams compose parallely or concurrently. In a composed stream, at
186-- any point of time more than one stream can run concurrently and yield
187-- elements. The two parallel types 'ParallelT' and 'CoparallelT' differ in how
188-- they merge streams together in a 'Semigroup' or 'Monad' composition. As
189-- these streams compose concurrently, the sequence of items in a composed
190-- stream cannot be determined by the position of elements in the constituent
191-- streams. The elements are yielded by the composed stream as they are
192-- generated by the constituent streams on a first come first serve basis.
193-- Therefore, on each run the stream may yield elements in a different sequence
194-- depending on the delays introduced by scheduling.
196-- $zipping
197--
198-- 'ZipSerial' and 'ZipParallel', provide 'Applicative' instances for zipping the
199-- corresponding elements of two streams together. Note that these types are
200-- not monads.
202-- $sum
203-- The 'Semigroup' operation '<>' of each stream type combines two streams in a
204-- type specific manner. This section provides polymorphic versions of '<>'
205-- which can be used to combine two streams in a predetermined way irrespective
206-- of the type.
208-- $adapters
209--
210-- You may want to use different stream types at different points in your
211-- program. Stream types can be converted or adapted from one type to another
212-- to make them interwork with each other.
213--
214-- To adapt from one monomorphic type (e.g. 'ParallelT') to another monomorphic
215-- type (e.g. 'SerialT') use the 'adapt' combinator. To give a polymorphic code
216-- a specific interpretation or to adapt a specific type to a polymorphic type
217-- use the type specific combinators e.g. 'parallely' or 'coserially'. You
218-- cannot adapt polymorphic code to polymorphic code, as it would not know
219-- which specific type you are converting from or to. If you see a an
220-- @ambiguous type variable@ error then most likely you are using 'adapt'
221-- unnecessarily on polymorphic code.
222--
224-- $foldutils
225--
226-- These are variants of standard 'Foldable' fold functions that use a
227-- polymorphic stream sum operation (e.g. 'parallel' or 'coserial') to fold a
228-- container of streams.