on master help sign in
Remove some deprecated modules
commitdb06710987e67da91d7c651ad495005b4e383b6a authorHarendra Kumar <harendra@composewell.com> dateWed 22 Nov 2023, 07:02 (3 years ago) parente7bb4d0
5 files changed+1−844
src/Streamly.hs−625 src/Streamly/Data/Unicode/Stream.hs−99 src/Streamly/Internal/Data/Array/ArrayMacros.h−40 src/Streamly/Memory/Array.hs−74 streamly.cabal+1−6
src/Streamly.hsdeleted−625
@@ -1,625 +0,0 @@
1−{-# OPTIONS_GHC -Wno-deprecations #-}
2−
3−-- |
4−-- Module : Streamly
5−-- Copyright : (c) 2017 Composewell Technologies
6−--
7−-- License : BSD3
8−-- Maintainer : streamly@composewell.com
9−-- Stability : experimental
10−-- Portability : GHC
11−--
12−-- Streamly is a general purpose programming framework using cocnurrent data
13−-- flow programming paradigm. It can be considered as a generalization of
14−-- Haskell lists to monadic streaming with concurrent composition capability.
15−-- The serial stream type in streamly @SerialT m a@ is like the list type @[a]@
16−-- parameterized by the monad @m@. For example, @SerialT IO a@ is a moral
17−-- equivalent of @[a]@ in the IO monad. Streams are constructed very much like
18−-- lists, except that they use 'nil' and 'cons' instead of '[]' and ':'.
19−--
20−-- @
21−-- > import "Streamly"
22−-- > import "Streamly.Prelude" (cons, consM)
23−-- > import qualified "Streamly.Prelude" as S
24−-- >
25−-- > S.toList $ 1 \`cons` 2 \`cons` 3 \`cons` nil
26−-- [1,2,3]
27−-- @
28−--
29−-- Unlike lists, streams can be constructed from monadic effects:
30−--
31−-- @
32−-- > S.'toList' $ 'getLine' \`consM` 'getLine' \`consM` S.'nil'
33−-- hello
34−-- world
35−-- ["hello","world"]
36−-- @
37−--
38−-- Streams are processed just like lists, with list like combinators, except
39−-- that they are monadic and work in a streaming fashion. Here is a simple
40−-- console echo program example:
41−--
42−-- @
43−-- > S.drain $ S.repeatM getLine & S.mapM putStrLn
44−-- @
45−--
46−-- @SerialT Identity a@ is a moral equivalent of pure lists. Streamly utilizes
47−-- fusion for high performance, therefore, we can represent and process strings
48−-- as streams of 'Char', encode and decode the streams to/from UTF8 and
49−-- serialize them to @Array Word8@ obviating the need for special purpose
50−-- libraries like @bytestring@ and @text@.
51−--
52−-- For more details
53−-- please see the "Streamly.Tutorial" module and the examples directory in this
54−-- package.
55−
56−{-# LANGUAGE NoMonomorphismRestriction #-}
57−
58−#include "inline.hs"
59−
60−module Streamly
61−{-# DEPRECATED "Please use \"Streamly.Data.Stream.Prelude\" from streamly package and \"Streamly.Data.Fold\" from streamly-core package instead." #-}
62− (
63− -- -- * Concepts Overview
64− -- -- ** Streams
65− -- -- $streams
66−
67− -- -- ** Folds
68− -- -- $folds
69−
70− -- -- ** Arrays
71− -- -- $arrays
72−
73− -- * Module Overview
74− -- $streamtypes
75−
76− -- * Type Synonyms
77− MonadAsync
78−
79− -- * Stream transformers
80− -- | A stream represents a sequence of pure or effectful actions. The
81− -- `cons` and `consM` operations and the corresponding operators '.:' and
82− -- '|:' can be used to join pure values or effectful actions in a sequence.
83− -- The effects in the stream can be executed in many different ways
84− -- depending on the type of stream. In other words, the behavior of 'consM'
85− -- depends on the type of the stream.
86− --
87− -- There are three high level categories of streams, /spatially ordered/
88− -- streams, /speculative/ streams and /time ordered/ streams. Spatially
89− -- ordered streams, 'SerialT' and 'WSerialT', execute the effects in serial
90− -- order i.e. one at a time and present the outputs of those effects to the
91− -- consumer in the same order. Speculative streams, 'AheadT', may execute
92− -- many effects concurrently but present the outputs to the consumer in the
93− -- specified spatial order. Time ordered streams, 'AsyncT', 'WAsyncT' and
94− -- 'ParallelT', may execute many effects concurrently and present the
95− -- outputs of those effects to the consumer in time order i.e. as soon as
96− -- the output is generated.
97− --
98− -- We described above how the effects in a sequence are executed for
99− -- different types of streams. The behvavior of the 'Semigroup' and 'Monad'
100− -- instances follow the behavior of 'consM'. Stream generation operations
101− -- like 'repeatM' also execute the effects differently for different
102− -- streams, providing a concurrent generation capability when used with
103− -- stream types that execute effects concurrently. Similarly, effectful
104− -- transformation operations like 'mapM' also execute the transforming
105− -- effects differently for different types of streams.
106−
107− -- ** Serial Streams
108− -- $serial
109− , SerialT
110− , WSerialT
111−
112− -- ** Speculative Streams
113− -- $ahead
114− , AheadT
115−
116− -- ** Asynchronous Streams
117− -- $async
118− , AsyncT
119− , WAsyncT
120− , ParallelT
121−
122− -- ** Zipping Streams
123− -- $zipping
124− , ZipSerialM
125− , ZipAsyncM
126−
127− -- * Parallel Function Application
128− -- $application
129− , (IP.|$)
130− , (IP.|&)
131− , (IP.|$.)
132− , (IP.|&.)
133− , mkAsync
134−
135− -- * Merging Streams
136− -- $sum
137− , serial
138− , wSerial
139− , ahead
140− , async
141− , wAsync
142− , parallel
143−
144− -- * Concurrency Control
145− -- $concurrency
146− , maxThreads
147− , maxBuffer
148−
149− -- * Rate Limiting
150− , Rate (..)
151− , rate
152− , avgRate
153− , minRate
154− , maxRate
155− , constRate
156−
157− -- * Stream Type Adapters
158− -- $adapters
159− , IsStream ()
160−
161− , serially
162− , wSerially
163− , asyncly
164− , aheadly
165− , wAsyncly
166− , parallely
167− , zipSerially
168− , zipAsyncly
169− , adapt
170−
171− -- * IO Streams
172− , Serial
173− , WSerial
174− , Ahead
175− , Async
176− , WAsync
177− , Parallel
178− , ZipSerial
179− , ZipAsync
180−
181− -- ** Folding Containers of Streams
182− -- | These are variants of standard 'Foldable' fold functions that use a
183− -- polymorphic stream sum operation (e.g. 'async' or 'wSerial') to fold a
184− -- finite container of streams. Note that these are just special cases of
185− -- the more general 'concatMapWith' operation.
186− --
187− , foldWith
188− , foldMapWith
189− , forEachWith
190−
191− -- * Re-exports
192− , Semigroup (..)
193− -- * Deprecated
194− , runStream
195− )
196−where
197−
198−import Data.Semigroup (Semigroup(..))
199−import Streamly.Internal.Control.Concurrent (MonadAsync)
200−import Streamly.Internal.Data.SVar (Rate(..))
201−import Streamly.Internal.Data.Stream.Ahead
202−import Streamly.Internal.Data.Stream.Async
203−import Streamly.Internal.Data.Stream.IsStream.Combinators
204−import Streamly.Internal.Data.Stream.IsStream.Expand
205−import Streamly.Internal.Data.Stream.IsStream.Type
206−
207−import qualified Streamly.Prelude as P
208−import qualified Streamly.Internal.Data.Stream.IsStream as IP
209−import qualified Streamly.Internal.Data.Stream.IsStream.Transform as Transform
210−
211−-- XXX provide good succinct examples of pipelining, merging, splitting etc.
212−-- below.
213−--
214−-- $streams
215−--
216−-- A program is expressed as a network of streams and folds. A stream is a
217−-- source or generator of data elements and a fold is a consumer of data elements that
218−-- reduces multiple input elements to a single value.
219−--
220−-- In the following example, a 'Word8' stream is generated by using
221−-- 'Streamly.FileSystem.Handle.read' on a file handle, then the
222−-- 'Streamly.Prelude.splitBySuffix' transformation splits the stream on
223−-- newlines (ascii value 10); it uses the 'Streamly.Data.Fold.drain' fold to reduce
224−-- the resulting lines to unit values (@()@), 'Streamly.Prelude.length' fold
225−-- then counts the unit elements in the resulting stream which gives us the
226−-- number of lines in the file:
227−--
228−-- > S.length $ S.splitOnSuffix FL.drain 10 $ FH.read fh
229−--
230−-- The following example folds the lines to arrays of 'Word8' using the
231−-- 'Streamly.Data.Array.Foreign.writeF' fold and then wraps the lines in square
232−-- brackets before writing them to standard output using
233−-- 'Streamly.FileSystem.Handle.write':
234−--
235−-- > wrapLine ln = S.fromList "[" <> A.read ln <> S.fromList "]\n"
236−-- > readLines = S.splitOnSuffix A.writeF 10
237−-- > FH.write stdout $ S.concatMap wrapLine $ readLines fh1
238−--
239−-- One stream can be appended after another:
240−--
241−-- > FH.write stdout $ S.concatMap wrapLine $ readLines fh1 <> readLines fh2
242−--
243−-- The following example reads two files concurrently, merges the lines from
244−-- the two streams and writes the resulting stream to another file:
245−--
246−-- > FH.write stdout $ S.concatMap wrapLine $ readLines fh1 `parallel` readLines fh2
247−--
248−-- There are many ways to generate, merge, zip, transform and fold data
249−-- streams. Many transformations can be chained in a stream pipeline. See
250−-- "Streamly.Prelude" module for combinators to manipulate streams.
251−
252−-- $folds
253−--
254−-- The way stream types in this module like 'SerialT' represent data sources,
255−-- the same way the 'Fold' type from "Streamly.Data.Fold" represents data sinks or
256−-- reducers of streams. Reducers can be combined to consume a stream source in
257−-- many ways. The simplest is to reduce a stream source using a fold e.g.:
258−--
259−-- > S.fold FL.length $ S.enumerateTo 100
260−--
261−-- Folds are consumers of streams and can be used to split a stream into
262−-- multiple independent flows. Grouping transforms a stream by applying a fold
263−-- on segments of a stream, distributing applies multiple folds in parallel on
264−-- the same stream and combines them, partitioning sends different elements of
265−-- a stream to different folds, unzipping divides the elements of a stream into
266−-- parts and sends them through different folds. Parsers are nothing but a
267−-- particular type of folds. Transformations can be applied contravariantly on
268−-- the input of a fold.
269−--
270−-- @
271−--
272−-- |---transform----Fold m a b--------|
273−-- ---stream m a-->transform-->| |---f b c ...
274−-- |---transform----Fold m a c--------|
275−-- | |
276−-- ...
277−-- @
278−--
279−
280−-- $arrays
281−--
282−-- Streamly arrays (See "Streamly.Data.Array.Foreign") complement streams to provide an
283−-- efficient computing paradigm. Streams are suitable for immutable
284−-- transformations of /potentially infinite/ data using /sequential access/ and
285−-- pipelined transformations whereas arrays are suitable for in-place
286−-- transformations of /necessarily finite/ data using /random access/. Streams
287−-- are synonymous with /sequential pipelined processing/ whereas arrays are
288−-- synonymous with /efficient buffering and random access/.
289−--
290−-- In general, a data processing pipeline reads data from some IO device, does
291−-- some processing on it and finally writes the output to another IO device.
292−-- Streams provide the overall framework of sequential processing pipeline in
293−-- which arrays are used as buffering elements in the middle. In addition to
294−-- buffering in the middle, arrays can also be used at the boundaries of the
295−-- pipeline to efficiently interface with external storage systems like memory,
296−-- files and network. If streams are the pipes in a water pipeline network
297−-- then arrays are like the storage tanks in the middle. On the input side,
298−-- think of arrays as buckets to fetch water to feed the pipeline and on the
299−-- output side buckets to remove the processed water.
300−--
301−-- 'ByteString' data type from the 'bytestring' package and the 'Text' data
302−-- type from the 'text' package are special cases of arrays. 'ByteString' is
303−-- like @Array Word8@ and 'Text' is like @utf16@ encoded @Array Word8@.
304−-- Streamly arrays can be transformed as efficiently as @bytestring@ or @text@
305−-- by using stream operations on them.
306−
307−-- Streams and arrays are equally important in computing. They are computing
308−-- duals of each other.
309−
310−-- $streamtypes
311−-- The basic stream type is 'Serial', it represents a sequence of IO actions,
312−-- and is a 'Monad'. The type 'SerialT' is a monad transformer that can
313−-- represent a sequence of actions in an arbitrary monad. The type 'Serial' is
314−-- in fact a synonym for @SerialT IO@. There are a few more types similar to
315−-- 'SerialT', all of them represent a stream and differ only in the
316−-- 'Semigroup', 'Applicative' and 'Monad' compositions of the stream. 'Serial'
317−-- and 'WSerial' types compose serially whereas 'Async' and 'WAsync'
318−-- types compose concurrently. All these types can be freely inter-converted
319−-- using type combinators without any cost. You can freely switch to any type
320−-- of composition at any point in the program. When no type annotation or
321−-- explicit stream type combinators are used, the default stream type is
322−-- inferred as 'Serial'.
323−--
324−-- This module exports stream types, instances and combinators for:
325−--
326−-- * converting between different stream types
327−-- * appending and concurrently merging streams
328−-- * Concurrency control
329−-- * Concurrent function application
330−-- * Stream rate control
331−--
332−-- This module is designed to be imported unqualified:
333−--
334−-- @
335−-- import Streamly
336−-- @
337−--
338−-- See the "Streamly.Prelude" module for APIs for construction,
339−-- generation, elimination and transformation of streams.
340−
341−------------------------------------------------------------------------------
342−-- Eliminating a stream
343−------------------------------------------------------------------------------
344−
345−-- | Same as "Streamly.Prelude.runStream".
346−--
347−{-# DEPRECATED runStream "Please use Streamly.Prelude.drain instead." #-}
348−runStream :: Monad m => SerialT m a -> m ()
349−runStream = P.drain
350−
351−{-
352−-- | Same as "Streamly.Prelude.foldWith".
353−--
354−{-# DEPRECATED foldWith "Please use Streamly.Prelude.foldWith instead." #-}
355−{-# INLINABLE foldWith #-}
356−foldWith :: (IsStream t, Foldable f)
357− => (t m a -> t m a -> t m a) -> f (t m a) -> t m a
358−foldWith = P.foldWith
359−
360−-- | Same as "Streamly.Prelude.foldMapWith".
361−--
362−{-# DEPRECATED foldMapWith "Please use Streamly.Prelude.foldMapWith instead." #-}
363−{-# INLINABLE foldMapWith #-}
364−foldMapWith :: (IsStream t, Foldable f)
365− => (t m b -> t m b -> t m b) -> (a -> t m b) -> f a -> t m b
366−foldMapWith = P.foldMapWith
367−
368−-- | Same as "Streamly.Prelude.forEachWith".
369−--
370−{-# DEPRECATED forEachWith "Please use Streamly.Prelude.forEachWith instead." #-}
371−{-# INLINABLE forEachWith #-}
372−forEachWith :: (IsStream t, Foldable f)
373− => (t m b -> t m b -> t m b) -> f a -> (a -> t m b) -> t m b
374−forEachWith = P.forEachWith
375−-}
376−
377−-- XXX Deprecate it in 0.8.0
378−--
379−-- | Make a stream asynchronous, triggers the computation and returns a stream
380−-- in the underlying monad representing the output generated by the original
381−-- computation. The returned action is exhaustible and must be drained once. If
382−-- not drained fully we may have a thread blocked forever and once exhausted it
383−-- will always return 'empty'.
384−--
385−-- @since 0.2.0
386−{-# INLINABLE mkAsync #-}
387−mkAsync :: (IsStream t, MonadAsync m) => t m a -> m (t m a)
388−mkAsync = return . Transform.mkAsync
389−
390−------------------------------------------------------------------------------
391−-- Documentation
392−------------------------------------------------------------------------------
393−
394−-- $serial
395−--
396−-- When a stream consumer demands an element from a serial stream constructed
397−-- as @a \`consM` b \`consM` ... nil@, the action @a@ at the head of the stream
398−-- sequence is executed and the result is supplied to the consumer. When the
399−-- next element is demanded, the action @b@ is executed and its result is
400−-- supplied. Thus, the effects are performed and results are consumed strictly
401−-- in a serial order. Serial streams can be considered as /spatially ordered/
402−-- streams as the order of execution and consumption is the same as the spatial
403−-- order in which the actions are composed by the programmer.
404−--
405−-- Serial streams enforce the side effects as well as the results of the
406−-- actions to be in the same order in which the actions are added to the
407−-- stream. Therefore, the semigroup operation for serial streams is not
408−-- commutative:
409−--
410−-- @
411−-- a <> b is not the same as b <> a
412−-- @
413−--
414−-- There are two serial stream types 'SerialT' and 'WSerialT'. The stream
415−-- evaluation of both the variants works in the same way as described above,
416−-- they differ only in the 'Semigroup' and 'Monad' implementaitons.
417−
418−-- $ahead
419−--
420−-- When a stream consumer demands an element from a speculative stream
421−-- constructed as @a \`consM` b \`consM` ... nil@, the action @a@ at the head
422−-- of the stream is executed and the output of the action is supplied to the
423−-- consumer. However, in addition to the action at the head multiple actions
424−-- following it may also be executed concurrently and the results buffered.
425−-- When the next element is demanded it may be served from the buffer and we
426−-- may execute the next action in the sequence to keep the buffer adequately
427−-- filled. Thus, the actions are executed concurrently but results consumed in
428−-- serial order just like serial streams. `consM` can be used to fold an
429−-- infinite lazy container of effects, as the number of concurrent executions
430−-- is limited.
431−--
432−-- Similar to 'consM', the monadic stream generation (e.g. replicateM) and
433−-- transformation operations (e.g. mapM) on speculative streams can execute
434−-- multiple effects concurrently in a speculative manner.
435−--
436−-- How many effects can be executed concurrently and how many results can be
437−-- buffered are controlled by 'maxThreads' and 'maxBuffer' combinators
438−-- respectively. The actual number of concurrent threads is adjusted according
439−-- to the rate at which the consumer is consuming the stream. It may even
440−-- execute actions serially in a single thread if that is enough to match the
441−-- consumer's speed.
442−--
443−-- Speculative streams enforce ordering of the results of actions in the stream
444−-- but the side effects are only partially ordered. Therefore, the semigroup
445−-- operation for speculative streams is not commutative from the pure outputs
446−-- perspective but commutative from side effects perspective.
447−
448−-- $async
449−--
450−-- /Scheduling and execution:/ In an asynchronous stream @a \`consM` b \`consM`
451−-- c ...@, the actions @a@, @b@, and @c@ are executed concurrently with the
452−-- consumer of the stream. The actions are /scheduled/ for execution in the
453−-- same order as they are specified in the stream. Multiple scheduled actions
454−-- may be /executed/ concurrently in parallel threads of execution. The
455−-- actions may be executed out of order and they may complete at arbitrary
456−-- times. Therefore, the /effects/ of the actions may be observed out of
457−-- order.
458−--
459−-- /Buffering:/ The /results/ from multiple threads of execution are queued in
460−-- a buffer as soon as they become available. The consumer of the stream is
461−-- served from this buffer. Therefore, the consumer may observe the results to
462−-- be out of order. In other words, an asynchronous stream is an unordered
463−-- stream i.e. order does not matter.
464−--
465−-- /Concurrency control:/ Threads are suspended if the `maxBuffer` limit is
466−-- reached, and resumed when the consumer makes space in the buffer. The
467−-- maximum number of concurrent threads depends on `maxThreads`. Number of
468−-- threads is increased or decreased based on the speed of the consumer.
469−--
470−-- /Generation operations:/ Concurrent stream generation operations e.g.
471−-- 'Streamly.Prelude.replicateM' when used in async style schedule and execute
472−-- the stream generating actions in the manner described above. The generation
473−-- actions run concurrently, effects and results of the actions as observed by
474−-- the consumer of the stream may be out of order.
475−--
476−-- /Transformation operations:/ Concurrent stream transformation operations
477−-- e.g. 'Streamly.Prelude.mapM', when used in async style, schedule and
478−-- execute transformation actions in the manner described above. Transformation
479−-- actions run concurrently, effects and results of the actions may be
480−-- observed by the consumer out of order.
481−--
482−-- /Variants:/ There are two asynchronous stream types 'AsyncT' and 'WAsyncT'.
483−-- They are identical with respect to single stream evaluation behavior. Their
484−-- behaviors differ in how they combine multiple streams using 'Semigroup' or
485−-- 'Monad' composition. Since the order of elements does not matter in
486−-- asynchronous streams the 'Semigroup' operation is effectively commutative.
487−
488−-- $zipping
489−--
490−-- 'ZipSerialM' and 'ZipAsyncM', provide 'Applicative' instances for zipping the
491−-- corresponding elements of two streams together. Note that these types are
492−-- not monads.
493−
494−-- $application
495−--
496−-- Stream processing functions can be composed in a chain using function
497−-- application with or without the '$' operator, or with reverse function
498−-- application operator '&'. Streamly provides concurrent versions of these
499−-- operators applying stream processing functions such that each stage of the
500−-- stream can run in parallel. The operators start with a @|@; we can read '|$'
501−-- as "@parallel dollar@" to remember that @|@ comes before '$'.
502−--
503−-- Imports for the code snippets below:
504−--
505−-- @
506−-- import Streamly
507−-- import qualified Streamly.Prelude as S
508−-- import Control.Concurrent
509−-- @
510−
511−-- $sum
512−-- The 'Semigroup' operation '<>' of each stream type combines two streams in a
513−-- type specific manner. This section provides polymorphic versions of '<>'
514−-- which can be used to combine two streams in a predetermined way irrespective
515−-- of the type.
516−
517−-- XXX An alternative design choice would be to let a control parameter affect
518−-- the nearest SVar only and then it gets cleared. The benefit of the current
519−-- choice is that it is simply just like global configuration, just like state
520−-- behaves, so should be easy to comprehend. But it has the downside of leaking
521−-- to undesired actions, that is we can forget to reset it.
522−--
523−-- $concurrency
524−--
525−-- These combinators can be used at any point in a stream composition to set
526−-- parameters to control the concurrency of the /argument stream/. A control
527−-- parameter set at any point remains effective for any concurrent combinators
528−-- used in the argument stream until it is reset by using the combinator again.
529−-- These control parameters have no effect on non-concurrent combinators in the
530−-- stream, or on non-concurrent streams.
531−--
532−-- /Pitfall:/ Remember that 'maxBuffer' in the following example applies to
533−-- 'mapM' and any other combinators that may follow it, and it does not apply
534−-- to the combinators before it:
535−--
536−-- @
537−-- ...
538−-- $ maxBuffer 10
539−-- $ S.mapM ...
540−-- ...
541−-- @
542−--
543−-- If we use '&' instead of '$' the situation will reverse, in the following
544−-- example, 'maxBuffer' does not apply to 'mapM', it applies to combinators
545−-- that come before it, because those are the arguments to 'maxBuffer':
546−--
547−-- @
548−-- ...
549−-- & maxBuffer 10
550−-- & S.mapM ...
551−-- ...
552−-- @
553−
554−-- $adapters
555−--
556−-- You may want to use different stream composition styles at different points
557−-- in your program. Stream types can be freely converted or adapted from one
558−-- type to another. The 'IsStream' type class facilitates type conversion of
559−-- one stream type to another. It is not used directly, instead the type
560−-- combinators provided below are used for conversions.
561−--
562−-- To adapt from one monomorphic type (e.g. 'AsyncT') to another monomorphic
563−-- type (e.g. 'SerialT') use the 'adapt' combinator. To give a polymorphic code
564−-- a specific interpretation or to adapt a specific type to a polymorphic type
565−-- use the type specific combinators e.g. 'fromAsync' or 'fromWSerial'. You
566−-- cannot adapt polymorphic code to polymorphic code, as the compiler would not know
567−-- which specific type you are converting from or to. If you see a an
568−-- @ambiguous type variable@ error then most likely you are using 'adapt'
569−-- unnecessarily on polymorphic code.
570−
571−-- | Same as 'Streamly.Prelude.concatFoldableWith'
572−--
573−-- @since 0.1.0
574−{-# DEPRECATED foldWith "Please use 'Streamly.Prelude.concatFoldableWith' instead." #-}
575−{-# INLINEABLE foldWith #-}
576−foldWith :: (IsStream t, Foldable f) => (t m a -> t m a -> t m a) -> f (t m a) -> t m a
577−foldWith = P.concatFoldableWith
578−
579−-- | Same as 'Streamly.Prelude.concatMapFoldableWith'
580−--
581−-- @since 0.1.0
582−{-# DEPRECATED foldMapWith "Please use 'Streamly.Prelude.concatMapFoldableWith' instead." #-}
583−{-# INLINEABLE foldMapWith #-}
584−foldMapWith :: (IsStream t, Foldable f) => (t m b -> t m b -> t m b) -> (a -> t m b) -> f a -> t m b
585−foldMapWith = P.concatMapFoldableWith
586−
587−-- | Same as 'Streamly.Prelude.concatForFoldableWith'
588−--
589−-- @since 0.1.0
590−{-# DEPRECATED forEachWith "Please use 'Streamly.Prelude.concatForFoldableWith' instead." #-}
591−{-# INLINEABLE forEachWith #-}
592−forEachWith :: (IsStream t, Foldable f) => (t m b -> t m b -> t m b) -> f a -> (a -> t m b) -> t m b
593−forEachWith = P.concatForFoldableWith
594−
595−{-# DEPRECATED serially "Please use 'Streamly.Prelude.fromSerial' instead." #-}
596−serially :: IsStream t => SerialT m a -> t m a
597−serially = fromSerial
598−
599−{-# DEPRECATED wSerially "Please use 'Streamly.Prelude.fromWSerial' instead." #-}
600−wSerially :: IsStream t => WSerialT m a -> t m a
601−wSerially = fromWSerial
602−
603−{-# DEPRECATED asyncly "Please use 'Streamly.Prelude.fromAsync' instead." #-}
604−asyncly :: IsStream t => AsyncT m a -> t m a
605−asyncly = fromAsync
606−
607−{-# DEPRECATED aheadly "Please use 'Streamly.Prelude.fromAhead' instead." #-}
608−aheadly :: IsStream t => AheadT m a -> t m a
609−aheadly = fromAhead
610−
611−{-# DEPRECATED wAsyncly "Please use 'Streamly.Prelude.fromWAsync' instead." #-}
612−wAsyncly :: IsStream t => WAsyncT m a -> t m a
613−wAsyncly = fromWAsync
614−
615−{-# DEPRECATED parallely "Please use 'Streamly.Prelude.fromParallel' instead." #-}
616−parallely :: IsStream t => ParallelT m a -> t m a
617−parallely = fromParallel
618−
619−{-# DEPRECATED zipSerially "Please use 'Streamly.Prelude.fromZipSerial' instead." #-}
620−zipSerially :: IsStream t => ZipSerialM m a -> t m a
621−zipSerially = fromZipSerial
622−
623−{-# DEPRECATED zipAsyncly "Please use 'Streamly.Prelude.fromZipAsync' instead." #-}
624−zipAsyncly :: IsStream t => ZipAsyncM m a -> t m a
625−zipAsyncly = fromZipAsync
src/Streamly/Data/Unicode/Stream.hsdeleted−99
@@ -1,99 +0,0 @@
1−-- |
2−-- Module : Streamly.Data.Unicode.Stream
3−-- Copyright : (c) 2018 Composewell Technologies
4−--
5−-- License : BSD3
6−-- Maintainer : streamly@composewell.com
7−-- Stability : experimental
8−-- Portability : GHC
9−--
10−-- = Processing Unicode Strings
11−--
12−-- A 'Char' stream is the canonical representation to process Unicode strings.
13−-- It can be processed efficiently using regular stream processing operations.
14−-- A byte stream of Unicode text read from an IO device or from an
15−-- 'Streamly.Data.Array.Foreign.Array' in memory can be decoded into a 'Char' stream
16−-- using the decoding routines in this module. A 'String' (@[Char]@) can be
17−-- converted into a 'Char' stream using 'Streamly.Prelude.fromList'. An @Array
18−-- Char@ can be 'Streamly.Prelude.unfold'ed into a stream using the array
19−-- 'Streamly.Data.Array.Foreign.read' unfold.
20−--
21−-- = Storing Unicode Strings
22−--
23−-- A stream of 'Char' can be encoded into a byte stream using the encoding
24−-- routines in this module and then written to IO devices or to arrays in
25−-- memory.
26−--
27−-- If you have to store a 'Char' stream in memory you can convert it into a
28−-- 'String' using 'Streamly.Prelude.toList' or using the
29−-- 'Streamly.Data.Fold.toList' fold. The 'String' type can be more efficient
30−-- than pinned arrays for short and short lived strings.
31−--
32−-- For longer or long lived streams you can 'Streamly.Prelude.fold' the 'Char'
33−-- stream as @Array Char@ using the array 'Streamly.Data.Array.Foreign.write' fold.
34−-- The 'Array' type provides a more compact representation and pinned memory
35−-- reducing GC overhead. If space efficiency is a concern you can use
36−-- 'encodeUtf8'' on the 'Char' stream before writing it to an 'Array' providing
37−-- an even more compact representation.
38−--
39−-- = String Literals
40−--
41−-- @Stream Identity Char@ and @Array Char@ are instances of 'IsString' and
42−-- 'IsList', therefore, 'OverloadedStrings' and 'OverloadedLists' extensions
43−-- can be used for convenience when specifying unicode strings literals using
44−-- these types.
45−--
46−-- = Pitfalls
47−--
48−-- * Case conversion: Some unicode characters translate to more than one code
49−-- point on case conversion. The 'toUpper' and 'toLower' functions in @base@
50−-- package do not handle such characters. Therefore, operations like @map
51−-- toUpper@ on a character stream or character array may not always perform
52−-- correct conversion.
53−-- * String comparison: In some cases, visually identical strings may have
54−-- different unicode representations, therefore, a character stream or
55−-- character array cannot be directly compared. A normalized comparison may be
56−-- needed to check string equivalence correctly.
57−--
58−-- = Experimental APIs
59−--
60−-- Some experimental APIs to conveniently process text using the
61−-- @Array Char@ represenation directly can be found in
62−-- "Streamly.Internal.Memory.Unicode.Array".
63−
64−-- XXX an unpinned array representation can be useful to store short and short
65−-- lived strings in memory.
66−--
67−module Streamly.Data.Unicode.Stream
68− {-# DEPRECATED "Please use Streamly.Unicode.Stream module from the streamly-core package." #-}
69− (
70− -- * Construction (Decoding)
71− decodeLatin1
72− , decodeUtf8
73−
74− -- * Elimination (Encoding)
75− , encodeLatin1
76− , encodeUtf8
77− {-
78− -- * Operations on character strings
79− , strip -- (dropAround isSpace)
80− , stripEnd
81− , stripStart
82− -}
83− -- Not exposing these yet as we have consider these with respect to Unicode
84− -- segmentation routines which are yet to be implemented.
85− -- -- * Transformation
86− -- , lines
87− -- , words
88− -- , unlines
89− -- , unwords
90−
91− -- * Deprecations
92− , decodeUtf8Lax
93− , encodeLatin1Lax
94− , encodeUtf8Lax
95− )
96−where
97−
98−import Streamly.Internal.Unicode.Stream
99−import Prelude hiding (lines, words, unlines, unwords)
src/Streamly/Internal/Data/Array/ArrayMacros.hdeleted−40
@@ -1,40 +0,0 @@
1−-------------------------------------------------------------------------------
2−-- Macros to access array pointers
3−-------------------------------------------------------------------------------
4−
5−-- The Storable instance of () has size 0. We ensure that the size is non-zero
6−-- to avoid a zero sized element and issues due to that.
7−-- See https://mail.haskell.org/pipermail/libraries/2022-January/thread.html
8−--
9−-- XXX Check the core to see if max can be statically eliminated. llvm can
10−-- eliminate the comparison, but not sure if GHC NCG can.
11−#define SIZE_OF(a) max 1 (sizeOf (Proxy :: Proxy a))
12−#define STORABLE_SIZE_OF(a) max 1 (sizeOf (undefined :: a))
13−
14−-- Move the pointer to ith element of specified type. Type is specified as the
15−-- type variable in the signature of the function where this macro is used.
16−#define PTR_NEXT(ptr,a) ptr `plusPtr` STORABLE_SIZE_OF(a)
17−#define PTR_PREV(ptr,a) ptr `plusPtr` negate (STORABLE_SIZE_OF(a))
18−
19−#define PTR_INDEX(ptr,i,a) ptr `plusPtr` (STORABLE_SIZE_OF(a) * i)
20−#define PTR_RINDEX(ptr,i,a) ptr `plusPtr` negate (STORABLE_SIZE_OF(a) * (i + 1))
21−
22−-- XXX If we know that the array is guaranteed to have size multiples of the
23−-- element size then we can use a simpler check saying "ptr < end". Since we
24−-- always allocate in multiples of elem we can use the simpler check and assert
25−-- the rigorous check.
26−#define PTR_VALID(ptr,end,a) ptr `plusPtr` STORABLE_SIZE_OF(a) <= end
27−#define PTR_INVALID(ptr,end,a) ptr `plusPtr` STORABLE_SIZE_OF(a) > end
28−
29−-------------------------------------------------------------------------------
30−-- Macros to access array indices
31−-------------------------------------------------------------------------------
32−
33−#define INDEX_NEXT(i,a) i + SIZE_OF(a)
34−#define INDEX_PREV(i,a) i - SIZE_OF(a)
35−
36−#define INDEX_OF(base,i,a) base + (SIZE_OF(a) * i)
37−#define RINDEX_OF(base,i,a) base - (SIZE_OF(a) * (i + 1))
38−
39−#define INDEX_VALID(i,end,a) i + SIZE_OF(a) <= end
40−#define INDEX_INVALID(i,end,a) i + SIZE_OF(a) > end
src/Streamly/Memory/Array.hsdeleted−74
@@ -1,74 +0,0 @@
1−#include "inline.hs"
2−
3−-- |
4−-- Module : Streamly.Memory.Array
5−-- Copyright : (c) 2019 Composewell Technologies
6−--
7−-- License : BSD3
8−-- Maintainer : streamly@composewell.com
9−-- Stability : experimental
10−-- Portability : GHC
11−--
12−-- This module provides immutable arrays in pinned memory (non GC memory)
13−-- suitable for long lived data storage, random access and for interfacing with
14−-- the operating system.
15−--
16−-- Arrays in this module are chunks of pinned memory that hold a sequence of
17−-- 'Storable' values of a given type, they cannot store non-serializable data
18−-- like functions. Once created an array cannot be modified. Pinned memory
19−-- allows efficient buffering of long lived data without adding any impact to
20−-- GC. One array is just one pointer visible to GC and it does not have to be
21−-- copied across generations. Moreover, pinned memory allows communication
22−-- with foreign consumers and producers (e.g. file or network IO) without
23−-- copying the data.
24−--
25−-- = Programmer Notes
26−--
27−-- To apply a transformation to an array use 'read' to unfold the array into a
28−-- stream, apply a transformation on the stream and then use 'write' to fold it
29−-- back to an array.
30−--
31−-- This module is designed to be imported qualified:
32−--
33−-- > import qualified Streamly.Array as A
34−--
35−-- For experimental APIs see "Streamly.Internal.Data.Array".
36−
37−module Streamly.Memory.Array
38− {-# DEPRECATED "Please use Streamly.Data.Array module from the streamly-core package." #-}
39− (
40− A.Array
41−
42− -- * Arrays
43− -- ** Construction
44− -- | When performance matters, the fastest way to generate an array is
45− -- 'writeN'. 'IsList' and 'IsString' instances can be
46− -- used to conveniently construct arrays from literal values.
47− -- 'OverloadedLists' extension or 'fromList' can be used to construct an
48− -- array from a list literal. Similarly, 'OverloadedStrings' extension or
49− -- 'fromList' can be used to construct an array from a string literal.
50−
51− -- Pure List APIs
52− , A.fromListN
53− , A.fromList
54−
55− -- Monadic APIs
56− , A.writeN -- drop new
57− , A.write -- full buffer
58− -- , writeLastN -- drop old (ring buffer)
59−
60− -- ** Elimination
61− -- 'GHC.Exts.toList' from "GHC.Exts" can be used to convert an array to a
62− -- list.
63−
64− , A.toList
65− , A.read
66−
67− -- ** Random Access
68− , A.length
69− -- , (!!)
70− -- , A.readIndex
71− )
72−where
73−
74−import Streamly.Internal.Data.Array as A
streamly.cabal+1−6
@@ -96,7 +96,6 @@ extra-source-files:
9696
9797 -- This is duplicated
9898 src/Streamly/Internal/Data/Stream/Instances.hs
99− src/Streamly/Internal/Data/Array/ArrayMacros.h
10099
101100 src/Streamly/Internal/FileSystem/Event/Darwin.h
102101 src/assert.hs
@@ -356,7 +355,6 @@ library
356355 include-dirs:
357356 src
358357 , src/Streamly/Internal/Data/Stream
359− , src/Streamly/Internal/Data/Array
360358
361359 hs-source-dirs: src
362360 exposed-modules:
@@ -380,7 +378,6 @@ library
380378 , Streamly.Internal.Data.Fold.Concurrent.Channel.Type
381379 , Streamly.Internal.Data.Fold.Concurrent.Channel
382380 , Streamly.Internal.Data.Fold.Concurrent
383− , Streamly.Data.Fold.Tee
384381
385382 , Streamly.Internal.Data.Stream.Concurrent.Channel.Type
386383 , Streamly.Internal.Data.Stream.Concurrent.Channel.Dispatcher
@@ -412,10 +409,8 @@ library
412409 , Streamly.Network.Inet.TCP
413410
414411 -- Deprecated
415− , Streamly
416− , Streamly.Data.Unicode.Stream
417− , Streamly.Memory.Array
418412 , Streamly.Data.Array.Foreign
413+ , Streamly.Data.Fold.Tee
419414 , Streamly.Prelude
420415
421416 -- Deprecated Internal modules