on master help sign in
Merge pull request #215 from composewell/string-docs
b7d0527Harendra Kumar
docs/streamly-vs-async.md+4−4
@@ -36,7 +36,7 @@ generalization of the IO monad with non-deterministic composition of streams
36added on top.
36added on top.
37
37
38However, if you would like to just run only some concurrent portions of your
38However, if you would like to just run only some concurrent portions of your
39−program using streamly, you can do that too. Just use `runStream` if you want
39+program using streamly, you can do that too. Just use `drain` if you want
40to run the stream without collecting the outputs of the concurrent actions or
40to run the stream without collecting the outputs of the concurrent actions or
41use `toList` if you want to convert the output stream into a list. Other
41use `toList` if you want to convert the output stream into a list. Other
42stream folding operations can also be used, see the docs for more details.
42stream folding operations can also be used, see the docs for more details.
@@ -84,10 +84,10 @@ return 2 first and then 1.
84
84
85### concurrently_
85### concurrently_
86
86
87−Use `runStream` instead of `toList` to run the actions but ignore the results:
87+Use `drain` instead of `toList` to run the actions but ignore the results:
88
88
89```haskell
89```haskell
90− runStream $ parallely $ getURL 1 |: getURL 2 |: S.nil
90+ S.drain $ parallely $ getURL 1 |: getURL 2 |: S.nil
91```
91```
92
92
93### Concurrent Applicative
93### Concurrent Applicative
@@ -135,7 +135,7 @@ other actions will be canceled, for example:
135 instance Exception Result
135 instance Exception Result
136
136
137 main = do
137 main = do
138− url <- try $ runStream $ parallely $
138+ url <- try $ S.drain $ parallely $
139 (getURL 2 >>= throwM . Result)
139 (getURL 2 >>= throwM . Result)
140 |: (getURL 1 >>= throwM . Result)
140 |: (getURL 1 >>= throwM . Result)
141 |: S.nil
141 |: S.nil
src/Streamly/String.hs+56−1
@@ -16,6 +16,9 @@
16-- stream fusion. If strings are to be stored or buffered in memory, they can
16-- stream fusion. If strings are to be stored or buffered in memory, they can
17-- be encoded to 'Word8' arrays using the encoding routines provided in the
17-- be encoded to 'Word8' arrays using the encoding routines provided in the
18-- module. Therefore, a separate type for text representation is not required.
18-- module. Therefore, a separate type for text representation is not required.
19+-- A @Stream Identity Char@ can be used almost as a drop-in replacement for the
20+-- standard Haskell @String@, especially when used with @OverloadedStrings@
21+-- extension, with little differences.
19
22
20-- The 'String' type in this module is just a synonym for the type @List Char@.
23-- The 'String' type in this module is just a synonym for the type @List Char@.
21-- It provides better performance compared to the standard Haskell @String@
24-- It provides better performance compared to the standard Haskell @String@
@@ -49,6 +52,7 @@ module Streamly.String
49 -- * Operations on character strings
52 -- * Operations on character strings
50 , strip -- (dropAround isSpace)
53 , strip -- (dropAround isSpace)
51 , stripEnd-}
54 , stripEnd-}
55+ -- * Substrings
52 , stripStart
56 , stripStart
53 , foldLines
57 , foldLines
54 , foldWords
58 , foldWords
@@ -153,14 +157,27 @@ stripEnd :: IsStream t => t m Char -> t m Char
153stripEnd = undefined
157stripEnd = undefined
154-}
158-}
155
159
160+-- | Remove leading whitespace from a String.
161+--
162+-- > stripStart = S.dropWhile isSpace
156{-# INLINE stripStart #-}
163{-# INLINE stripStart #-}
157stripStart :: (Monad m, IsStream t) => t m Char -> t m Char
164stripStart :: (Monad m, IsStream t) => t m Char -> t m Char
158stripStart = S.dropWhile isSpace
165stripStart = S.dropWhile isSpace
159
166
167+-- | Fold each line of the stream using the supplied Fold
168+-- and stream the result.
169+--
170+-- >>> S.toList $ foldLines (S.fromList "lines\nthis\nstring\n\n\n") FL.toList
171+-- ["lines", "this", "string", "", ""]
160{-# INLINE foldLines #-}
172{-# INLINE foldLines #-}
161foldLines :: (Monad m, IsStream t) => t m Char -> Fold m Char b -> t m b
173foldLines :: (Monad m, IsStream t) => t m Char -> Fold m Char b -> t m b
162foldLines = flip (FL.splitSuffixBy (== '\n'))
174foldLines = flip (FL.splitSuffixBy (== '\n'))
163
175
176+-- | Fold each word of the stream using the supplied Fold
177+-- and stream the result.
178+--
179+-- >>> S.toList $ foldWords (S.fromList "fold these words") FL.toList
180+-- ["fold", "these", "words"]
164{-# INLINE foldWords #-}
181{-# INLINE foldWords #-}
165foldWords :: (Monad m, IsStream t) => t m Char -> Fold m Char b -> t m b
182foldWords :: (Monad m, IsStream t) => t m Char -> Fold m Char b -> t m b
166foldWords = flip (FL.wordsBy isSpace)
183foldWords = flip (FL.wordsBy isSpace)
@@ -168,7 +185,7 @@ foldWords = flip (FL.wordsBy isSpace)
168foreign import ccall unsafe "u_iswspace"
185foreign import ccall unsafe "u_iswspace"
169 iswspace :: Int -> Int
186 iswspace :: Int -> Int
170
187
171−-- Code copied from base/Data.Char to INLINE it
188+-- | Code copied from base/Data.Char to INLINE it
172{-# INLINE isSpace #-}
189{-# INLINE isSpace #-}
173isSpace :: Char -> Bool
190isSpace :: Char -> Bool
174isSpace c
191isSpace c
@@ -177,18 +194,56 @@ isSpace c
177 where
194 where
178 uc = fromIntegral (ord c) :: Word
195 uc = fromIntegral (ord c) :: Word
179
196
197+-- | Break a string up into a list of strings at newline characters.
198+-- The resulting strings do not contain newlines.
199+--
200+-- >>> S.toList $ lines $ S.fromList "lines\nthis\nstring\n\n\n"
201+-- ["lines","this","string","",""]
202+--
203+-- If you're dealing with lines of massive length, consider using
204+-- 'foldLines' instead.
180{-# INLINE lines #-}
205{-# INLINE lines #-}
181lines :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
206lines :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
182lines = FL.splitSuffixBy (== '\n') toArray
207lines = FL.splitSuffixBy (== '\n') toArray
183
208
209+-- | Break a string up into a list of strings, which were delimited
210+-- by characters representing white space.
211+--
212+-- >>> S.toList $ words $ S.fromList "A newline\nis considered white space?"
213+-- ["A", "newline", "is", "considered", "white", "space?"]
214+--
215+-- If you're dealing with words of massive length, consider using
216+-- 'foldWords' instead.
184{-# INLINE words #-}
217{-# INLINE words #-}
185words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
218words :: (MonadIO m, IsStream t) => t m Char -> t m (Array Char)
186words = FL.wordsBy isSpace toArray
219words = FL.wordsBy isSpace toArray
187
220
221+-- | Flattens the stream of @Array Char@, after appending a terminating
222+-- newline to each string.
223+--
224+-- 'unlines' is an inverse operation to 'lines'.
225+--
226+-- >>> S.toList $ unlines $ S.fromList ["lines", "this", "string"]
227+-- "lines\nthis\nstring\n"
228+--
229+-- Note that, in general
230+--
231+-- > unlines . lines /= id
188{-# INLINE unlines #-}
232{-# INLINE unlines #-}
189unlines :: (MonadIO m, IsStream t) => t m (Array Char) -> t m Char
233unlines :: (MonadIO m, IsStream t) => t m (Array Char) -> t m Char
190unlines = D.fromStreamD . A.unlines '\n' . D.toStreamD
234unlines = D.fromStreamD . A.unlines '\n' . D.toStreamD
191
235
236+-- | Flattens the stream of @Array Char@, after appending a separating
237+-- space to each string.
238+--
239+-- 'unwords' is an inverse operation to 'words'.
240+--
241+-- >>> S.toList $ unwords $ S.fromList ["unwords", "this", "string"]
242+-- "unwords this string"
243+--
244+-- Note that, in general
245+--
246+-- > unwords . words /= id
192{-# INLINE unwords #-}
247{-# INLINE unwords #-}
193unwords :: (MonadAsync m, IsStream t) => t m (Array Char) -> t m Char
248unwords :: (MonadAsync m, IsStream t) => t m (Array Char) -> t m Char
194unwords = A.flattenArrays . (S.intersperse (A.fromList " "))
249unwords = A.flattenArrays . (S.intersperse (A.fromList " "))