-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathStreamK.hs
More file actions
217 lines (188 loc) · 6.17 KB
/
StreamK.hs
File metadata and controls
217 lines (188 loc) · 6.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
{-# LANGUAGE CPP #-}
-- |
-- Module : Streamly.Data.StreamK
-- Copyright : (c) 2017 Composewell Technologies
--
-- License : BSD3
-- Maintainer : streamly@composewell.com
-- Stability : released
-- Portability : GHC
--
-- Streams represented as chains of function calls using Continuation Passing
-- Style (CPS), suitable for dynamically and recursively composing potentially
-- large number of streams. The 'K' in 'StreamK' stands for Kontinuation.
--
-- In addition to the combinators in this module, you can use operations from
-- "Streamly.Data.Stream" for StreamK as well by converting StreamK to Stream
-- ('toStream'), and vice-versa ('fromStream'). Please refer to
-- "Streamly.Internal.Data.StreamK" for more functions that have not yet been
-- released.
--
-- For documentation see the corresponding combinators in
-- "Streamly.Data.Stream". Documentation has been omitted in this module unless
-- there is a difference worth mentioning or if the combinator does not exist
-- in "Streamly.Data.Stream".
--
-- == Fused vs CPS Streams
--
-- Unlike the statically fused operations in "Streamly.Data.Stream", StreamK
-- operations are less efficient, involving a function call overhead for each
-- element, but they exhibit linear O(n) time complexity wrt to the number of
-- stream compositions. Therefore, they are suitable for dynamically composing
-- streams e.g. appending potentially infinite streams in recursive loops.
-- While fused streams can be used efficiently to process elements as small as
-- a single byte, CPS streams are typically used on bigger chunks of data to
-- avoid the larger overhead per element.
--
-- = Overview
--
-- StreamK can be constructed like lists, except that they use 'nil' instead of
-- '[]' and 'cons' instead of ':'.
--
-- >>> import Streamly.Data.StreamK (StreamK, cons, consM, nil)
--
-- `cons` constructs a stream from pure values:
--
-- >>> stream = 1 `cons` 2 `cons` nil :: StreamK IO Int
--
-- Operations from "Streamly.Data.Stream" can be used for StreamK as well by
-- converting StreamK to Stream ('toStream'), and vice-versa ('fromStream').
--
-- >>> Stream.fold Fold.toList $ StreamK.toStream stream -- IO [Int]
-- [1,2]
--
-- Stream can also be constructed from effects not just pure values:
--
-- >>> effect n = print n >> return n
-- >>> stream = effect 1 `consM` effect 2 `consM` nil
-- >>> Stream.fold Fold.toList $ StreamK.toStream stream
-- 1
-- 2
-- [1,2]
-- Notes:
--
-- primitive/open loop operations that can be used recursively e.g. uncons,
-- foldBreak, parseBreak should not be converted from StreamD for use in
-- StreamK, instead native StreamK impl should be used.
--
-- Closed loop operations like repeat, replicate, iterate etc can be converted
-- from StreamD.
--
-- In the last phase any operation like (toStreamK . f . toStreamD) should be
-- rewritten to a K version of f.
-- XXX Need to add rewrite rules for all missing StreamD operations.
--
module Streamly.Data.StreamK
(
-- * Setup
-- | To execute the code examples provided in this module in ghci, please
-- run the following commands first.
--
-- $setup
-- * Type
StreamK
-- -- * Nested
-- -- | List transformers and logic programming monads.
-- , Nested(..) -- need to decide on mtl instances
-- , FairNested(..) -- bind is not associative
-- * Construction
-- ** Primitives
-- | Primitives to construct a stream from pure values or monadic actions.
-- All other stream construction and generation combinators described later
-- can be expressed in terms of these primitives. However, the special
-- versions provided in this module can be much more efficient in some
-- cases. Users can create custom combinators using these primitives.
, nil
, nilM
, cons
, consM
-- ** From Values
, fromPure
, fromEffect
-- ** From Stream
-- | Please note that 'Stream' type does not observe any exceptions from
-- the consumer of the stream whereas 'StreamK' does.
, fromStream
, toStream
-- ** From Containers
, fromFoldable
-- ** To Containers
, toList
-- * Elimination
-- ** Primitives
, uncons
, drain
-- -- ** Folding
-- , foldBreak
-- ** Parsing
, toParserK
, parse
, parseBreak
, parsePos
, parseBreakPos
-- * Transformation
, mapM
, dropWhile
, take
, filter
-- * Combining Two Streams
-- | Unlike the operations in "Streamly.Data.Stream", these operations can
-- be used to dynamically compose large number of streams e.g. using the
-- 'concatMapWith' and 'mergeMapWith' operations. They have a linear O(n)
-- time complexity wrt to the number of streams being composed.
-- ** Appending
, append
-- ** Interleaving
, interleave
-- ** Merging
, mergeBy
, mergeByM
-- ** Zipping
, zipWith
, zipWithM
-- ** Cross Product
-- XXX is "bind/concatFor" better to have than crossWith?
-- crossWith f xs1 xs2 = concatFor xs1 (\x -> fmap (f x) xs2)
, crossWith
-- , cross
-- , joinInner
-- , CrossStreamK (..)
-- * Stream of streams
-- | Some useful idioms:
--
-- >>> concatFoldableWith f = Prelude.foldr f StreamK.nil
-- >>> concatMapFoldableWith f g = Prelude.foldr (f . g) StreamK.nil
-- >>> concatForFoldableWith f xs g = Prelude.foldr (f . g) StreamK.nil xs
--
, concatEffect
, concatMap
, bfsConcatMap
, fairConcatMap
, concatMapWith
, concatFor
, bfsConcatFor
, fairConcatFor
, concatForM
, bfsConcatForM
, fairConcatForM
, mergeMapWith
-- * Buffered Operations
, reverse
, sortBy
-- * Exceptions
-- | Please note that 'Stream' type does not observe any exceptions from
-- the consumer of the stream whereas 'StreamK' does.
, handle
-- * Resource Management
-- | Please note that 'Stream' type does not observe any exceptions from
-- the consumer of the stream whereas 'StreamK' does.
, bracketIO
-- * Deprecated
, parseBreakChunks
, parseChunks
)
where
import Streamly.Internal.Data.StreamK
import Prelude hiding
(reverse, zipWith, mapM, dropWhile, take, filter, concatMap)
#include "DocTestDataStreamK.hs"