Hello community,
here is the log from the commit of package ghc-streaming-bytestring for
openSUSE:Factory checked in at 2017-03-20 17:06:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-streaming-bytestring (Old)
and /work/SRC/openSUSE:Factory/.ghc-streaming-bytestring.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-streaming-bytestring"
Mon Mar 20 17:06:26 2017 rev:2 rq:454904 version:0.1.4.6
Changes:
--------
---
/work/SRC/openSUSE:Factory/ghc-streaming-bytestring/ghc-streaming-bytestring.changes
2016-11-02 12:40:17.000000000 +0100
+++
/work/SRC/openSUSE:Factory/.ghc-streaming-bytestring.new/ghc-streaming-bytestring.changes
2017-03-20 17:06:28.412042407 +0100
@@ -1,0 +2,10 @@
+Thu Jan 26 16:22:10 UTC 2017 - [email protected]
+
+- Update to version 0.1.4.6 with cabal2obs.
+
+-------------------------------------------------------------------
+Sun Jan 8 21:13:40 UTC 2017 - [email protected]
+
+- Update to version 0.1.4.5 with cabal2obs.
+
+-------------------------------------------------------------------
Old:
----
streaming-bytestring-0.1.4.4.tar.gz
New:
----
streaming-bytestring-0.1.4.6.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ghc-streaming-bytestring.spec ++++++
--- /var/tmp/diff_new_pack.gYLdlN/_old 2017-03-20 17:06:29.971822166 +0100
+++ /var/tmp/diff_new_pack.gYLdlN/_new 2017-03-20 17:06:29.975821601 +0100
@@ -1,7 +1,7 @@
#
# spec file for package ghc-streaming-bytestring
#
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,16 +17,16 @@
%global pkg_name streaming-bytestring
+%bcond_with tests
Name: ghc-%{pkg_name}
-Version: 0.1.4.4
+Version: 0.1.4.6
Release: 0
Summary: Effectful byte steams, or: bytestring io done right
License: BSD-3-Clause
-Group: System/Libraries
+Group: Development/Languages/Other
Url: https://hackage.haskell.org/package/%{pkg_name}
Source0:
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
BuildRequires: ghc-Cabal-devel
-# Begin cabal-rpm deps:
BuildRequires: ghc-bytestring-devel
BuildRequires: ghc-deepseq-devel
BuildRequires: ghc-exceptions-devel
@@ -38,7 +38,11 @@
BuildRequires: ghc-transformers-base-devel
BuildRequires: ghc-transformers-devel
BuildRoot: %{_tmppath}/%{name}-%{version}-build
-# End cabal-rpm deps
+%if %{with tests}
+BuildRequires: ghc-smallcheck-devel
+BuildRequires: ghc-tasty-devel
+BuildRequires: ghc-tasty-smallcheck-devel
+%endif
%description
This is an implementation of effectful, memory-constrained bytestrings (byte
@@ -195,14 +199,14 @@
%prep
%setup -q -n %{pkg_name}-%{version}
-
%build
%ghc_lib_build
-
%install
%ghc_lib_install
+%check
+%cabal_test
%post devel
%ghc_pkg_recache
++++++ streaming-bytestring-0.1.4.4.tar.gz ->
streaming-bytestring-0.1.4.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/streaming-bytestring-0.1.4.4/Data/ByteString/Streaming/Char8.hs
new/streaming-bytestring-0.1.4.6/Data/ByteString/Streaming/Char8.hs
--- old/streaming-bytestring-0.1.4.4/Data/ByteString/Streaming/Char8.hs
2016-06-01 16:57:23.000000000 +0200
+++ new/streaming-bytestring-0.1.4.6/Data/ByteString/Streaming/Char8.hs
2017-01-17 09:12:48.000000000 +0100
@@ -1,5 +1,5 @@
{-# LANGUAGE CPP, BangPatterns #-}
-{-#LANGUAGE RankNTypes, OverloadedStrings #-}
+{-#LANGUAGE RankNTypes, OverloadedStrings, ScopedTypeVariables #-}
-- This library emulates Data.ByteString.Lazy.Char8 but includes a monadic
element
-- and thus at certain points uses a `Stream`/`FreeT` type in place of lists.
@@ -30,7 +30,6 @@
, mwrap
-
-- * Transforming ByteStrings
, map -- map :: Monad m => (Char -> Char) -> ByteString m r
-> ByteString m r
, intercalate -- intercalate :: Monad m => ByteString m () -> Stream
(ByteString m) m r -> ByteString m r
@@ -51,19 +50,12 @@
, uncons -- uncons :: Monad m => ByteString m r -> m (Either r
(Char, ByteString m r))
, nextChar
- -- * Direct chunk handling
- , unconsChunk
- , nextChunk -- nextChunk :: Monad m => ByteString m r -> m (Either
r (ByteString, ByteString m r))
- , consChunk
- , chunk
- , foldrChunks
- , foldlChunks
-
-- * Substrings
-- ** Breaking strings
, break -- break :: Monad m => (Char -> Bool) -> ByteString m r
-> ByteString m (ByteString m r)
, drop -- drop :: Monad m => GHC.Int.Int64 -> ByteString m r
-> ByteString m r
+ , dropWhile
, group -- group :: Monad m => ByteString m r -> Stream
(ByteString m) m r
, groupBy
, span -- span :: Monad m => (Char -> Bool) -> ByteString m r
-> ByteString m (ByteString m r)
@@ -77,8 +69,8 @@
, lines
, words
, denull
+
-- ** Special folds
-
, concat -- concat :: Monad m => Stream (ByteString m) m r ->
ByteString m r
-- * Builders
@@ -98,7 +90,7 @@
-- ** Unfolding ByteStrings
, unfoldr -- unfoldr :: (a -> Maybe (Char, a)) -> a -> ByteString
m ()
, unfoldM -- unfold :: (a -> Either r (Char, a)) -> a ->
ByteString m r
-
+ , reread
-- * Folds, including support for `Control.Foldl`
-- , foldr -- foldr :: Monad m => (Char -> a -> a) -> a ->
ByteString m () -> m a
, fold -- fold :: Monad m => (x -> Char -> x) -> x -> (x -> b)
-> ByteString m () -> m b
@@ -135,6 +127,19 @@
, hGetNonBlockingN -- hGetNonBlockingN :: Int -> Handle -> Int ->
ByteString IO ()
, hPut -- hPut :: Handle -> ByteString IO r -> IO r
-- , hPutNonBlocking -- hPutNonBlocking :: Handle -> ByteString IO r ->
ByteString IO r
+
+ -- * Simple chunkwise operations
+ , unconsChunk
+ , nextChunk
+ , chunk
+ , foldrChunks
+ , foldlChunks
+ , chunkFold
+ , chunkFoldM
+ , chunkMap
+ , chunkMapM
+ , chunkMapM_
+
-- * Etc.
-- , zipWithStream -- zipWithStream :: Monad m => (forall x. a ->
ByteString m x -> ByteString m x) -> [a] -> Stream (ByteString m) m r -> Stream
(ByteString m) m r
, distribute -- distribute :: ByteString (t m) a -> t (ByteString m)
a
@@ -174,7 +179,8 @@
appendFile, stdout, stdin, fromHandle, toHandle,
hGetContents, hGetContentsN, hGet, hGetN, hPut,
getContents, hGetNonBlocking,
- hGetNonBlockingN, readFile, writeFile, interact)
+ hGetNonBlockingN, readFile, writeFile, interact,
+ chunkFold, chunkFoldM, chunkMap, chunkMapM)
-- hPutNonBlocking,
import Control.Monad (liftM)
@@ -351,12 +357,14 @@
iterate :: (Char -> Char) -> Char -> ByteString m r
iterate f c = R.iterate (c2w . f . w2c) (c2w c)
+{-#INLINE iterate #-}
-- | @'repeat' x@ is an infinite ByteString, with @x@ the value of every
-- element.
--
repeat :: Char -> ByteString m r
repeat = R.repeat . c2w
+{-#INLINE repeat #-}
-- -- | /O(n)/ @'replicate' n x@ is a ByteString of length @n@ with @x@
-- -- the value of every element.
@@ -388,10 +396,12 @@
go a = case f a of
Nothing -> Nothing
Just (c,a) -> Just (c2w c, a)
-
+{-#INLINE unfoldM #-}
+
unfoldr :: (a -> Either r (Char, a)) -> a -> ByteString m r
unfoldr step = R.unfoldr (either Left (\(c,a) -> Right (c2w c,a)) . step)
+{-#INLINE unfoldr #-}
-- ---------------------------------------------------------------------
@@ -402,25 +412,27 @@
-- satisfy @p@.
takeWhile :: Monad m => (Char -> Bool) -> ByteString m r -> ByteString m ()
takeWhile f = R.takeWhile (f . w2c)
--- -- | 'dropWhile' @p xs@ returns the suffix remaining after 'takeWhile' @p
xs@.
--- dropWhile :: (Word8 -> Bool) -> ByteString -> ByteString
--- dropWhile f cs0 = dropWhile' cs0
--- where dropWhile' Empty = Empty
--- dropWhile' (Chunk c cs) =
--- case findIndexOrEnd (not . f) c of
--- n | n < B.length c -> Chunk (B.drop n c) cs
--- | otherwise -> dropWhile' cs
+{-#INLINE takeWhile #-}
+
+-- | 'dropWhile' @p xs@ returns the suffix remaining after 'takeWhile' @p xs@.
+
+dropWhile :: Monad m => (Char -> Bool) -> ByteString m r -> ByteString m r
+dropWhile f = R.dropWhile (f . w2c)
+{-#INLINE dropWhile #-}
{- | 'break' @p@ is equivalent to @'span' ('not' . p)@.
-}
break :: Monad m => (Char -> Bool) -> ByteString m r -> ByteString m
(ByteString m r)
break f = R.break (f . w2c)
+{-#INLINE break #-}
+
--
-- | 'span' @p xs@ breaks the ByteString into two segments. It is
-- equivalent to @('takeWhile' p xs, 'dropWhile' p xs)@
span :: Monad m => (Char -> Bool) -> ByteString m r -> ByteString m
(ByteString m r)
span p = break (not . p)
+{-#INLINE span #-}
-- -- | /O(n)/ Splits a 'ByteString' into components delimited by
-- -- separators, where the predicate returns True for a separator element.
@@ -483,29 +495,50 @@
This is the genuinely streaming 'lines' which only breaks chunks, and
thus never increases the use of memory.
-> lines :: Monad m => ByteString m r -> Stream (ByteString m) m r
+ Because 'ByteString's are usually read in binary mode, with no line
+ ending conversion, this function recognizes both @\\n@ and @\\r\\n@
+ endings (regardless of the current platform).
-}
-lines :: Monad m => ByteString m r -> Stream (ByteString m) m r
--- lines = loop
--- where
--- loop !x = case x of
--- Empty r -> Return r
--- Go m -> Effect $ liftM loop m
--- Chunk c0 cs0 -> comb [] (B.split 10 c0) cs0
-lines (Empty r) = Return r
-lines (Go m) = Effect $ liftM lines m
-lines (Chunk c0 cs0) = comb [] (B.split 10 c0) cs0 where
- comb !acc [] (Empty r) = Step (revChunks acc (Return r))
- comb acc [] (Chunk c cs) = comb acc (B.split 10 c) cs
- comb acc (s:[]) (Empty r) = Step (revChunks (s:acc) (Return r))
- comb acc (s:[]) (Chunk c cs) = comb (s:acc) (B.split 10 c) cs
- comb acc b (Go m) = Effect (liftM (comb acc b) m)
- comb acc (s:ss) cs = Step (revChunks (s:acc) (comb [] ss cs))
- revChunks cs r = L.foldl' (flip Chunk) (Empty r) cs
+lines :: forall m r . Monad m => ByteString m r -> Stream (ByteString m) m r
+lines text0 = loop1 text0
+ where
+ loop1 :: ByteString m r -> Stream (ByteString m) m r
+ loop1 text =
+ case text of
+ Empty r -> Return r
+ Go m -> Effect $ liftM loop1 m
+ Chunk c cs
+ | B.null c -> loop1 cs
+ | otherwise -> Step (loop2 text)
+ loop2 :: ByteString m r -> ByteString m (Stream (ByteString m) m r)
+ loop2 text =
+ case text of
+ Empty r -> Empty (Return r)
+ Go m -> Go $ liftM loop2 m
+ Chunk c cs ->
+ case B.elemIndex 10 c of
+ Nothing -> Chunk c (loop2 cs)
+ Just i ->
+ let prefixLength =
+ if i >= 1 && B.unsafeIndex c (i-1) == 13 -- \r\n (dos)
+ then i-1
+ else i
+ rest =
+ if B.length c > i+1
+ then Chunk (B.drop (i+1) c) cs
+ else cs
+ in Chunk (B.unsafeTake prefixLength c) (Empty (loop1 rest))
{-#INLINABLE lines #-}
--- | The 'unlines' function restores line breaks between layers
+-- | The 'unlines' function restores line breaks between layers.
+--
+-- Note that this is not a perfect inverse of 'lines':
+--
+-- * @'lines' . 'unlines'@ can produce more strings than there were if some of
+-- the \"lines\" had embedded newlines.
+--
+-- * @'unlines' . 'lines'@ will replace @\\r\\n@ with @\\n@.
unlines :: Monad m => Stream (ByteString m) m r -> ByteString m r
unlines = loop where
loop str = case str of
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/streaming-bytestring-0.1.4.4/Data/ByteString/Streaming/Internal.hs
new/streaming-bytestring-0.1.4.6/Data/ByteString/Streaming/Internal.hs
--- old/streaming-bytestring-0.1.4.4/Data/ByteString/Streaming/Internal.hs
2016-06-01 16:57:23.000000000 +0200
+++ new/streaming-bytestring-0.1.4.6/Data/ByteString/Streaming/Internal.hs
2017-01-17 09:12:48.000000000 +0100
@@ -14,6 +14,11 @@
, foldrChunksM -- :: Monad m => (ByteString -> m a -> m a) -> m a ->
ByteString m r -> m a
, foldlChunksM -- :: Monad m => (ByteString -> m a -> m a) -> m a ->
ByteString m r -> m a
+ , chunkFold
+ , chunkFoldM
+ , chunkMap
+ , chunkMapM
+ , chunkMapM_
, unfoldMChunks
, unfoldrChunks
@@ -88,8 +93,12 @@
instance Monad m => Applicative (ByteString m) where
pure = Empty
- (<*>) = ap
-
+ {-#INLINE pure #-}
+ bf <*> bx = do {f <- bf; x <- bx; Empty (f x)}
+ {-#INLINE (<*>) #-}
+ (*>) = (>>)
+ {-#INLINE (*>) #-}
+
instance Monad m => Monad (ByteString m) where
return = Empty
{-#INLINE return #-}
@@ -121,9 +130,9 @@
instance MFunctor ByteString where
hoist phi bs = case bs of
- Empty r -> Empty r
+ Empty r -> Empty r
Chunk bs' rest -> Chunk bs' (hoist phi rest)
- Go m -> Go (phi (liftM (hoist phi) m))
+ Go m -> Go (phi (liftM (hoist phi) m))
{-#INLINABLE hoist #-}
instance (r ~ ()) => IsString (ByteString m r) where
@@ -131,10 +140,10 @@
{-#INLINE fromString #-}
instance (m ~ Identity, Show r) => Show (ByteString m r) where
- show bs0 = case bs0 of
- Empty r -> "Empty (" ++ show r ++ ")"
+ show bs0 = case bs0 of -- the implementation this instance deserves ...
+ Empty r -> "Empty (" ++ show r ++ ")"
Go (Identity bs') -> "Go (Identity (" ++ show bs' ++ "))"
- Chunk bs'' bs -> "Chunk " ++ show bs'' ++ " (" ++ show bs ++ ")"
+ Chunk bs'' bs -> "Chunk " ++ show bs'' ++ " (" ++ show bs ++ ")"
instance (Monoid r, Monad m) => Monoid (ByteString m r) where
mempty = Empty mempty
@@ -150,7 +159,6 @@
throwM = lift . throwM
{-#INLINE throwM #-}
-
instance (MonadCatch m) => MonadCatch (ByteString m) where
catch str f = go str
where
@@ -214,7 +222,7 @@
materialize :: (forall x . (r -> x) -> (S.ByteString -> x -> x) -> (m x -> x)
-> x)
-> ByteString m r
materialize phi = phi Empty Chunk Go
-{-#INLINE materialize #-}
+{-#INLINE[0] materialize #-}
-- | Resolve a succession of chunks into its Church encoding; this is
-- not a safe operation; it is equivalent to exposing the constructors
@@ -227,7 +235,11 @@
Empty r -> nil r
Chunk b bs -> cons b (loop SPEC bs )
Go ms -> mwrap (liftM (loop SPEC) ms)
-{-# INLINABLE dematerialize #-}
+{-# INLINE [1] dematerialize #-}
+
+{-# RULES
+ "dematerialize/materialize" forall (phi :: forall b . (r -> b) ->
(S.ByteString -> b -> b) -> (m b -> b) -> b). dematerialize (materialize phi)
= phi ;
+ #-}
------------------------------------------------------------------------
-- The representation uses lists of packed chunks. When we have to convert from
@@ -347,6 +359,46 @@
go a (Go m) = m >>= go a
{-# INLINABLE foldlChunks #-}
+chunkMap :: Monad m => (S.ByteString -> S.ByteString) -> ByteString m r ->
ByteString m r
+chunkMap f bs = dematerialize bs return (\bs bss -> Chunk (f bs) bss) Go
+{-#INLINE chunkMap #-}
+
+chunkMapM :: Monad m => (S.ByteString -> m S.ByteString) -> ByteString m r ->
ByteString m r
+chunkMapM f bs = dematerialize bs return (\bs bss -> Go (liftM (flip Chunk
bss) (f bs))) Go
+{-#INLINE chunkMapM #-}
+
+chunkMapM_ :: Monad m => (S.ByteString -> m x) -> ByteString m r -> m r
+chunkMapM_ f bs = dematerialize bs return (\bs mr -> f bs >> mr) join
+{-#INLINE chunkMapM_ #-}
+
+
+{- | @chunkFold@ is preferable to @foldlChunks@ since it is
+ an appropriate argument for @Control.Foldl.purely@ which
+ permits many folds and sinks to be run simulaneously on one bytestream.
+
+ -}
+chunkFold :: Monad m => (x -> S.ByteString -> x) -> x -> (x -> a) ->
ByteString m r -> m (Of a r)
+chunkFold step begin done = go begin
+ where go a _ | a `seq` False = undefined
+ go a (Empty r) = return (done a :> r)
+ go a (Chunk c cs) = go (step a c) cs
+ go a (Go m) = m >>= go a
+{-# INLINABLE chunkFold #-}
+
+{- | @chunkFoldM@ is preferable to @foldlChunksM@ since it is
+ an appropriate argument for @Control.Foldl.impurely@ which
+ permits many folds and sinks to be run simulaneously on one bytestream.
+
+ -}
+chunkFoldM :: Monad m => (x -> S.ByteString -> m x) -> m x -> (x -> m a) ->
ByteString m r -> m (Of a r)
+chunkFoldM step begin done bs = begin >>= go bs
+ where
+ go str !x = case str of
+ Empty r -> done x >>= \a -> return (a :> r)
+ Chunk c cs -> step x c >>= go cs
+ Go m -> m >>= \str' -> go str' x
+{-# INLINABLE chunkFoldM #-}
+
foldlChunksM :: Monad m => (a -> S.ByteString -> m a) -> m a -> ByteString m r
-> m (Of a r)
foldlChunksM f z bs = z >>= \a -> go a bs
where
@@ -356,6 +408,8 @@
Go m -> m >>= go a
{-# INLINABLE foldlChunksM #-}
+
+
-- | Consume the chunks of an effectful ByteString with a natural right
monadic fold.
foldrChunksM :: Monad m => (S.ByteString -> m a -> m a) -> m a -> ByteString m
r -> m a
foldrChunksM step nil bs = dematerialize bs
@@ -397,7 +451,18 @@
{-# INLINABLE unfoldrChunks #-}
+{-| Stream chunks from something that contains @IO (Maybe ByteString)@
+ until it returns @Nothing@. @reread@ is of particular use rendering
@io-streams@
+ input streams as byte streams in the present sense
+
+> Q.reread Streams.read :: InputStream S.ByteString ->
Q.ByteString IO ()
+> Q.reread (liftIO . Streams.read) :: MonadIO m => InputStream S.ByteString
-> Q.ByteString m ()
+
+The other direction here is
+
+> Streams.unfoldM Q.unconsChunk :: Q.ByteString IO r -> IO (InputStream
S.ByteString)
+ -}
reread :: Monad m => (s -> m (Maybe S.ByteString)) -> s -> ByteString m ()
reread step s = loop where
loop = Go $ do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/streaming-bytestring-0.1.4.4/Data/ByteString/Streaming.hs
new/streaming-bytestring-0.1.4.6/Data/ByteString/Streaming.hs
--- old/streaming-bytestring-0.1.4.4/Data/ByteString/Streaming.hs
2016-06-01 16:57:23.000000000 +0200
+++ new/streaming-bytestring-0.1.4.6/Data/ByteString/Streaming.hs
2017-01-17 09:12:48.000000000 +0100
@@ -84,20 +84,13 @@
, uncons -- uncons :: Monad m => ByteString m r -> m (Either r
(Word8, ByteString m r))
, nextByte -- nextByte :: Monad m => ByteString m r -> m (Either r (Word8,
ByteString m r))
, denull
-
- -- * Direct chunk handling
- , unconsChunk
- , nextChunk -- nextChunk :: Monad m => ByteString m r -> m (Either
r (ByteString, ByteString m r))
- , consChunk
- , chunk
- , foldrChunks
- , foldlChunks
-- * Substrings
-- ** Breaking strings
, break -- break :: Monad m => (Word8 -> Bool) -> ByteString m
r -> ByteString m (ByteString m r)
, drop -- drop :: Monad m => GHC.Int.Int64 -> ByteString m r
-> ByteString m r
+ , dropWhile
, group -- group :: Monad m => ByteString m r -> Stream
(ByteString m) m r
, groupBy
, span -- span :: Monad m => (Word8 -> Bool) -> ByteString m r
-> ByteString m (ByteString m r)
@@ -130,11 +123,13 @@
-- ** Unfolding ByteStrings
, unfoldM -- unfoldr :: (a -> m (Maybe (Word8, a))) -> m a ->
ByteString m ()
, unfoldr -- unfold :: (a -> Either r (Word8, a)) -> a ->
ByteString m r
-
+ , reread
+
-- * Folds, including support for `Control.Foldl`
, foldr -- foldr :: Monad m => (Word8 -> a -> a) -> a ->
ByteString m () -> m a
, fold -- fold :: Monad m => (x -> Word8 -> x) -> x -> (x ->
b) -> ByteString m () -> m b
, fold_ -- fold' :: Monad m => (x -> Word8 -> x) -> x -> (x ->
b) -> ByteString m r -> m (b, r)
+
, head
, head_
, last
@@ -173,6 +168,17 @@
-- * Etc.
, zipWithStream -- zipWithStream :: Monad m => (forall x. a ->
ByteString m x -> ByteString m x) -> [a] -> Stream (ByteString m) m r -> Stream
(ByteString m) m r
+ -- * Simple chunkwise operations
+ , unconsChunk
+ , nextChunk
+ , chunk
+ , foldrChunks
+ , foldlChunks
+ , chunkFold
+ , chunkFoldM
+ , chunkMap
+ , chunkMapM
+ , chunkMapM_
) where
import Prelude hiding
@@ -533,14 +539,14 @@
return r
{-# INLINE snoc #-}
--- | /O(1)/ Extract the first element of a ByteString, which must be non-empty.
+-- | /O(1)/ Extract the first element of a 'ByteString', which must be
non-empty.
head_ :: Monad m => ByteString m r -> m Word8
head_ (Empty _) = error "head"
head_ (Chunk c _) = return $ S.unsafeHead c
head_ (Go m) = m >>= head_
{-# INLINE head_ #-}
--- | /O(c)/ Extract the first element of a ByteString, which must be non-empty.
+-- | /O(c)/ Extract the first element of a 'ByteString', which must be
non-empty.
head :: Monad m => ByteString m r -> m (Of (Maybe Word8) r)
head (Empty r) = return (Nothing :> r)
head (Chunk c rest) = case S.uncons c of
@@ -551,7 +557,7 @@
head (Go m) = m >>= head
{-# INLINE head #-}
--- | /O(1)/ Extract the head and tail of a ByteString, or Nothing
+-- | /O(1)/ Extract the head and tail of a 'ByteString', or 'Nothing'
-- if it is empty
uncons :: Monad m => ByteString m r -> m (Maybe (Word8, ByteString m r))
uncons (Empty _) = return Nothing
@@ -563,7 +569,7 @@
uncons (Go m) = m >>= uncons
{-# INLINABLE uncons #-}
--
--- | /O(1)/ Extract the head and tail of a ByteString, or its return value
+-- | /O(1)/ Extract the head and tail of a 'ByteString', or its return value
-- if it is empty. This is the \'natural\' uncons for an effectful byte stream.
nextByte :: Monad m => ByteString m r -> m (Either r (Word8, ByteString m r))
nextByte (Empty r) = return (Left r)
@@ -593,7 +599,7 @@
Go m -> m >>= nextChunk
{-# INLINABLE nextChunk #-}
--- | /O(n\/c)/ Extract the last element of a ByteString, which must be finite
+-- | /O(n\/c)/ Extract the last element of a 'ByteString', which must be finite
-- and non-empty.
last_ :: Monad m => ByteString m r -> m Word8
last_ (Empty _) = error "Data.ByteString.Streaming.last: empty string"
@@ -690,12 +696,12 @@
{-# INLINABLE intersperse #-}
-{- | 'foldr', applied to a binary operator, a starting value
+-- | 'foldr', applied to a binary operator, a starting value
-- (typically the right-identity of the operator), and a ByteString,
-- reduces the ByteString using the binary operator, from right to left.
-
-> foldr cons = id
--}
+--
+-- > foldr cons = id
+--
foldr :: Monad m => (Word8 -> a -> a) -> a -> ByteString m () -> m a
foldr k = foldrChunks (flip (S.foldr k))
{-# INLINE foldr #-}
@@ -715,7 +721,7 @@
{-# INLINABLE fold #-}
--- | 'fold\'' keeps the return value of the left-folded bytestring. Useful for
+-- | 'fold_' keeps the return value of the left-folded bytestring. Useful for
-- simultaneous folds over a segmented bytestream
fold_ :: Monad m => (x -> Word8 -> x) -> x -> (x -> b) -> ByteString m r -> m
(Of b r)
@@ -907,10 +913,10 @@
cycle = forever
{-# INLINE cycle #-}
--- | /O(n)/ The 'unfoldr' function is analogous to the Stream \'unfoldr\'.
+-- | /O(n)/ The 'unfoldr' function is analogous to the Stream @unfoldr@.
-- 'unfoldr' builds a ByteString from a seed value. The function takes
-- the element and returns 'Nothing' if it is done producing the
--- ByteString or returns 'Just' @(a,b)@, in which case, @a@ is a
+-- ByteString or returns @'Just' (a,b)@, in which case, @a@ is a
-- prepending to the ByteString and @b@ is used as the next element in a
-- recursive call.
@@ -925,8 +931,8 @@
{-# INLINABLE unfoldM #-}
-- | 'unfold' is like 'unfoldr' but stops when the co-algebra
--- returns 'Left'; the result is the return value of the 'ByteString m r'
--- 'unfoldr uncons = id'
+-- returns 'Left'; the result is the return value of the @ByteString m r@
+-- @unfoldr uncons = id@
unfoldr :: (a -> Either r (Word8, a)) -> a -> ByteString m r
unfoldr f s0 = unfoldChunk 32 s0
where unfoldChunk n s =
@@ -1027,14 +1033,17 @@
| otherwise -> Chunk c (takeWhile' cs)
{-# INLINABLE takeWhile #-}
--- -- | 'dropWhile' @p xs@ returns the suffix remaining after 'takeWhile' @p
xs@.
--- dropWhile :: (Word8 -> Bool) -> ByteString -> ByteString
--- dropWhile f cs0 = dropWhile' cs0
--- where dropWhile' Empty = Empty
--- dropWhile' (Chunk c cs) =
--- case findIndexOrEnd (not . f) c of
--- n | n < S.length c -> Chunk (S.drop n c) cs
--- | otherwise -> dropWhile' cs
+-- | 'dropWhile' @p xs@ returns the suffix remaining after 'takeWhile' @p xs@.
+dropWhile :: Monad m => (Word8 -> Bool) -> ByteString m r -> ByteString m r
+dropWhile pred = drop' where
+ drop' bs = case bs of
+ Empty r -> Empty r
+ Go m -> Go (liftM drop' m)
+ Chunk c cs -> case findIndexOrEnd (not.pred) c of
+ 0 -> Chunk c cs
+ n | n < S.length c -> Chunk (S.drop n c) cs
+ | otherwise -> drop' cs
+{-#INLINABLE dropWhile #-}
-- | 'break' @p@ is equivalent to @'span' ('not' . p)@.
break :: Monad m => (Word8 -> Bool) -> ByteString m r -> ByteString m
(ByteString m r)
@@ -1419,7 +1428,7 @@
c <- liftIO (S.hGetSome h k)
-- only blocks if there is no data available
if S.null c
- then Go $ liftIO (hClose h) >> return (Empty ())
+ then Empty ()
else Chunk c loop
{-#INLINABLE hGetContentsN #-} -- very effective inline pragma
@@ -1527,8 +1536,8 @@
return r
{-# INLINE writeFile #-}
-{-| Read an entire file into a chunked 'ByteString IO ()'.
- The Handle will be held open until EOF is encountered.
+{-| Read an entire file into a chunked @'ByteString' IO ()@.
+ The handle will be held open until EOF is encountered.
The block governed by 'Control.Monad.Trans.Resource.runResourceT'
will end with the closing of any handles opened.
@@ -1753,7 +1762,7 @@
{-#INLINABLE concatBuilders #-}
-{-| A simple construction of a builder from a byte stream.
+{-| A simple construction of a builder from a 'ByteString'.
>>> let aaa = "10000 is a number\n" :: Q.ByteString IO ()
>>> hPutBuilder IO.stdout $ toBuilder aaa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/streaming-bytestring-0.1.4.4/streaming-bytestring.cabal
new/streaming-bytestring-0.1.4.6/streaming-bytestring.cabal
--- old/streaming-bytestring-0.1.4.4/streaming-bytestring.cabal 2016-06-01
16:57:23.000000000 +0200
+++ new/streaming-bytestring-0.1.4.6/streaming-bytestring.cabal 2017-01-17
09:12:48.000000000 +0100
@@ -1,5 +1,5 @@
name: streaming-bytestring
-version: 0.1.4.4
+version: 0.1.4.6
synopsis: effectful byte steams, or: bytestring io done right.
description: This is an implementation of effectful,
memory-constrained
@@ -184,7 +184,7 @@
, mmorph >=1.0 && <1.2
, transformers >=0.3 && <0.6
, transformers-base
- , streaming >= 0.1.4.0 && < 0.1.4.5
+ , streaming >= 0.1.4.0 && < 0.1.4.8
, resourcet
, exceptions
if impl(ghc < 7.8)
@@ -199,3 +199,21 @@
default-language: Haskell2010
ghc-options: -O2
+test-suite test
+ default-language:
+ Haskell2010
+ type:
+ exitcode-stdio-1.0
+ hs-source-dirs:
+ tests
+ main-is:
+ test.hs
+ build-depends:
+ base >= 4 && < 5
+ , transformers
+ , tasty >= 0.11.0.4
+ , tasty-smallcheck >= 0.8.1
+ , smallcheck >= 1.1.1
+ , streaming
+ , streaming-bytestring
+ , bytestring
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/streaming-bytestring-0.1.4.4/tests/test.hs
new/streaming-bytestring-0.1.4.6/tests/test.hs
--- old/streaming-bytestring-0.1.4.4/tests/test.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/streaming-bytestring-0.1.4.6/tests/test.hs 2017-01-17
09:12:48.000000000 +0100
@@ -0,0 +1,47 @@
+import Test.Tasty
+import Test.Tasty.SmallCheck
+import Test.SmallCheck.Series
+
+import Control.Applicative
+import Data.Functor.Identity
+import qualified Data.ByteString.Char8 as BS8
+import qualified Data.ByteString.Streaming.Char8 as SBS8
+import Text.Printf
+import qualified Streaming.Prelude as S
+
+listOf :: Monad m => Series m a -> Series m [a]
+listOf a = decDepth $
+ pure [] \/ ((:) <$> a <~> listOf a)
+
+strSeries :: Monad m => Series m String
+strSeries = listOf (generate $ const ['a', 'b', '\n'])
+
+chunksSeries :: Monad m => Series m [String]
+chunksSeries = listOf strSeries
+
+fromChunks :: [String] -> SBS8.ByteString Identity ()
+fromChunks = SBS8.fromChunks . S.each . map BS8.pack
+
+unix2dos :: String -> String
+unix2dos = concatMap $ \c -> if c == '\n' then "\r\n" else [c]
+
+s_lines :: SBS8.ByteString Identity () -> [BS8.ByteString]
+s_lines
+ = runIdentity
+ . S.toList_
+ . S.mapped SBS8.toStrict
+ . SBS8.lines
+
+main = defaultMain $ testGroup "Tests"
+ [ testGroup "lines" $
+ [ testProperty "Data.ByteString.Streaming.Char8.lines is equivalent to
Prelude.lines" $ over chunksSeries $ \chunks ->
+ let expected = lines $ concat chunks
+ got = (map BS8.unpack . s_lines . fromChunks) chunks
+ in
+ if expected == got
+ then Right ""
+ else Left (printf "Expected %s; got %s" (show expected) (show got)
:: String)
+ , testProperty "lines recognizes DOS line endings" $ over strSeries $ \str
->
+ s_lines (SBS8.string $ unix2dos str) == s_lines (SBS8.string str)
+ ]
+ ]