streaming-utils-0.1.4.4: Experimental http-client, aeson, attoparsec, zlib and pipes utilities for use with the <http://hackage.haskell.org/package/streaming streaming> and <http://hackage.haskell.org/package/streaming-bytestring streaming bytestring> libraries. They generally closely follow similarly named modules in the pipes \'ecosystem\', using similar function names, where possible. Thus, for example, using the http client module, we might number the lines of a remote document thus: > import Streaming > import Streaming.Prelude (with, each) > import qualified Streaming.Prelude as S > import Data.ByteString.Streaming.HTTP > import qualified Data.ByteString.Streaming.Char8 as Q > > main = runResourceT $ do > let output = numbers <|> Q.lines (simpleHTTP "http://lpaste.net/raw/146542") > Q.putStrLn $ Q.unlines output > > numbers :: Monad m => Stream (Q.ByteString m) m () > numbers = with (each [1..]) $ \n -> Q.pack (each (show n ++ ". ")) > -- ["1. ", "2. " ..] The memory requirements of this @Prelude@-ish program will not be affected by the fact that, say, the third \'line\' is 10 terabytes long. This package of course heaps together a number of dependencies, as it seemed best not to spam hackage with numerous packages. If it seems reasonable to detach some of it, please raise an issue on the github page. Questions about usage can be raised as issues, or addressed to the <https://groups.google.com/forum/#!forum/haskell-pipes pipes list>.

Safe HaskellNone
LanguageHaskell2010

Data.Attoparsec.ByteString.Streaming

Description

Here is a simple use of parsed and standard Streaming segmentation devices to parse a file in which groups of numbers are separated by blank lines. Such a problem of 'nesting streams' is described in the conduit context in this StackOverflow question

-- $ cat nums.txt
-- 1
-- 2
-- 3
--
-- 4
-- 5
-- 6
--
-- 7
-- 8

We will sum the groups and stream the results to standard output:

import Streaming
import qualified Streaming.Prelude as S
import qualified Data.ByteString.Streaming.Char8 as Q
import qualified Data.Attoparsec.ByteString.Char8 as A
import qualified Data.Attoparsec.ByteString.Streaming as A
import Data.Function ((&))

main = Q.getContents           -- raw bytes
       & A.parsed lineParser   -- stream of parsed `Maybe Int`s; blank lines are `Nothing`
       & void                  -- drop any unparsed nonsense at the end
       & S.split Nothing       -- split on blank lines
       & S.maps S.concat       -- keep `Just x` values in the sub-streams (cp. catMaybes)
       & S.mapped S.sum        -- sum each substream
       & S.print               -- stream results to stdout

lineParser = Just <$> A.scientific <* A.endOfLine <|> Nothing <$ A.endOfLine
-- $ cat nums.txt | ./atto
-- 6.0
-- 15.0
-- 15.0

Synopsis

Documentation

parse :: Monad m => Parser a -> ByteString m x -> m (Either a Message, ByteString m x) Source #

The result of a parse (Either a ([String], String)), with the unconsumed byte stream.

>>> :set -XOverloadedStrings  -- the string literal below is a streaming bytestring
>>> (r,rest1) <- AS.parse (A.scientific <* A.many' A.space) "12.3  4.56  78.3"
>>> print r
Left 12.3
>>> (s,rest2) <- AS.parse (A.scientific <* A.many' A.space) rest1
>>> print s
Left 4.56
>>> (t,rest3) <- AS.parse (A.scientific <* A.many' A.space) rest2
>>> print t
Left 78.3
>>> Q.putStrLn rest3

parsed Source #

Arguments

:: Monad m 
=> Parser a

Attoparsec parser

-> ByteString m r

Raw input

-> Stream (Of a) m (Either (Message, ByteString m r) r) 

Apply a parser repeatedly to a stream of bytes, streaming the parsed values, but ending when the parser fails.or the bytes run out.

>>> S.print $ AS.parsed (A.scientific <* A.many' A.space) $ "12.3  4.56  78.9"
12.3
4.56
78.9
18.282