bytestring-tree-builder 0.2.7.10 → 0.2.7.11
raw patch · 7 files changed
+222/−205 lines, 7 filesdep −QuickCheckdep −deepseqdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies removed: QuickCheck, deepseq
Dependency ranges changed: base
API changes (from Hackage documentation)
Files
- benchmark/Main.hs +28/−27
- bytestring-tree-builder.cabal +84/−49
- library/ByteString/TreeBuilder.hs +55/−62
- library/ByteString/TreeBuilder/Poker.hs +4/−6
- library/ByteString/TreeBuilder/Prelude.hs +18/−20
- library/ByteString/TreeBuilder/Tree.hs +6/−13
- tasty/Main.hs +27/−28
benchmark/Main.hs view
@@ -1,54 +1,55 @@ module Main where import BasePrelude-import Control.DeepSeq+import qualified ByteString.TreeBuilder as A import Criterion.Main import Data.ByteString (ByteString)-import qualified ByteString.TreeBuilder as A -+main :: IO () main = defaultMain $- map sampleGroup $- [("Small Input", smallSample), ("Medium Input", mediumSample), ("Large Input", largeSample)]+ map sampleGroup $+ [("Small Input", smallSample), ("Medium Input", mediumSample), ("Large Input", largeSample)] sampleGroup :: (String, Sample) -> Benchmark sampleGroup (title, (Sample sample)) =- bench title $ nf sample $- (A.byteString, mappend, mempty, A.toByteString)+ bench title $+ nf sample $+ (A.byteString, mappend, mempty, A.toByteString) -newtype Sample =- Sample (forall a. (ByteString -> a, a -> a -> a, a, a -> ByteString) -> ByteString)+newtype Sample+ = Sample (forall a. (ByteString -> a, a -> a -> a, a, a -> ByteString) -> ByteString) {-# NOINLINE smallSample #-} smallSample :: Sample smallSample = Sample $- \ (fromByteString, (<>), mempty, toByteString) ->- toByteString $- (fromByteString "hello" <> fromByteString "asdf") <>- fromByteString "fsndfn" <>- (fromByteString "dfgknfg" <> fromByteString "aaaaaa")+ \(fromByteString, (<>), mempty, toByteString) ->+ toByteString $+ (fromByteString "hello" <> fromByteString "asdf")+ <> fromByteString "fsndfn"+ <> (fromByteString "dfgknfg" <> fromByteString "aaaaaa") {-# NOINLINE mediumSample #-} mediumSample :: Sample mediumSample = Sample $- \ (fromByteString, (<>), mempty, toByteString) ->- toByteString $- foldl' (<>) mempty $ replicate 1000 $- (fromByteString "hello" <> fromByteString "asdf") <>- fromByteString "fsndfn" <>- (fromByteString "dfgknfg" <> fromByteString "aaaaaa")+ \(fromByteString, (<>), mempty, toByteString) ->+ toByteString $+ foldl' (<>) mempty $+ replicate 1000 $+ (fromByteString "hello" <> fromByteString "asdf")+ <> fromByteString "fsndfn"+ <> (fromByteString "dfgknfg" <> fromByteString "aaaaaa") {-# NOINLINE largeSample #-} largeSample :: Sample largeSample = Sample $- \ (fromByteString, (<>), mempty, toByteString) ->- toByteString $- foldl' (<>) mempty $ replicate 100000 $- (fromByteString "hello" <> fromByteString "asdf") <>- fromByteString "fsndfn" <>- (fromByteString "dfgknfg" <> fromByteString "aaaaaa")-+ \(fromByteString, (<>), mempty, toByteString) ->+ toByteString $+ foldl' (<>) mempty $+ replicate 100000 $+ (fromByteString "hello" <> fromByteString "asdf")+ <> fromByteString "fsndfn"+ <> (fromByteString "dfgknfg" <> fromByteString "aaaaaa")
bytestring-tree-builder.cabal view
@@ -1,72 +1,107 @@-name: bytestring-tree-builder-version: 0.2.7.10-category: ByteString-synopsis: A very efficient ByteString builder implementation based on the binary tree+cabal-version: 3.0+name: bytestring-tree-builder+version: 0.2.7.11+category: ByteString+synopsis:+ A very efficient ByteString builder implementation based on the binary tree+ description: According to <https://github.com/nikita-volkov/bytestring-builders-benchmark the benchmarks> this builder implementation beats all the alternatives. It is especially well-suited for generating strict bytestrings, beating the standard builder by at least the factor of 4.-homepage: https://github.com/nikita-volkov/bytestring-tree-builder-bug-reports: https://github.com/nikita-volkov/bytestring-tree-builder/issues-author: Nikita Volkov <nikita.y.volkov@mail.ru>-maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>-copyright: (c) 2015, Nikita Volkov-license: MIT-license-file: LICENSE-build-type: Simple-cabal-version: >=1.10 +homepage: https://github.com/nikita-volkov/bytestring-tree-builder+bug-reports:+ https://github.com/nikita-volkov/bytestring-tree-builder/issues++author: Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>+copyright: (c) 2015, Nikita Volkov+license: MIT+license-file: LICENSE+ source-repository head- type: git+ type: git location: git://github.com/nikita-volkov/bytestring-tree-builder.git +common base+ default-language: Haskell2010+ default-extensions:+ NoImplicitPrelude+ NoMonomorphismRestriction+ Arrows+ BangPatterns+ ConstraintKinds+ DataKinds+ DefaultSignatures+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveGeneric+ DeriveTraversable+ EmptyDataDecls+ FlexibleContexts+ FlexibleInstances+ FunctionalDependencies+ GADTs+ GeneralizedNewtypeDeriving+ LambdaCase+ LiberalTypeSynonyms+ MagicHash+ MultiParamTypeClasses+ MultiWayIf+ OverloadedStrings+ ParallelListComp+ PatternGuards+ QuasiQuotes+ RankNTypes+ RecordWildCards+ ScopedTypeVariables+ StandaloneDeriving+ TemplateHaskell+ TupleSections+ TypeFamilies+ TypeOperators+ UnboxedTuples+ library- hs-source-dirs: library- default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples- default-language: Haskell2010+ import: base+ hs-source-dirs: library other-modules:- ByteString.TreeBuilder.Prelude ByteString.TreeBuilder.Poker+ ByteString.TreeBuilder.Prelude ByteString.TreeBuilder.Tree- exposed-modules:- ByteString.TreeBuilder++ exposed-modules: ByteString.TreeBuilder build-depends:- base >=4.11 && <5,- bytestring >=0.10 && <0.12,- text >=1 && <3+ , base >=4.13 && <5+ , bytestring >=0.10 && <0.12+ , text >=1 && <3 benchmark benchmark- type: exitcode-stdio-1.0+ import: base+ type: exitcode-stdio-1.0 hs-source-dirs: benchmark- main-is: Main.hs- ghc-options:- -O2- -threaded- "-with-rtsopts=-N"- -funbox-strict-fields- default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveTraversable, DeriveGeneric, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples- default-language: Haskell2010+ main-is: Main.hs+ ghc-options: -O2 -threaded -with-rtsopts=-N -funbox-strict-fields build-depends:- base-prelude,- bytestring,- bytestring-tree-builder,- criterion >=1.1 && <2,- deepseq ==1.*+ , base-prelude+ , bytestring+ , bytestring-tree-builder+ , criterion >=1.1 && <2 test-suite tasty- type: exitcode-stdio-1.0+ import: base+ type: exitcode-stdio-1.0 hs-source-dirs: tasty- main-is: Main.hs- default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples- default-language: Haskell2010+ main-is: Main.hs build-depends:- base-prelude,- bytestring,- bytestring-tree-builder,- QuickCheck >=2.14 && <3,- quickcheck-instances >=0.3.25 && <0.4,- tasty >=1.4 && <2,- tasty-hunit >=0.10 && <0.11,- tasty-quickcheck >=0.10 && <0.11+ , base-prelude+ , bytestring+ , bytestring-tree-builder+ , quickcheck-instances >=0.3.25 && <0.4+ , tasty >=1.4 && <2+ , tasty-hunit >=0.10 && <0.11+ , tasty-quickcheck >=0.10 && <0.11
library/ByteString/TreeBuilder.hs view
@@ -1,41 +1,42 @@ module ByteString.TreeBuilder-(- Builder,- -- * Declaration- -- ** Primitives- byteString,- byte,- -- ** Extras- asciiIntegral,- asciiChar,- utf8Char,- utf8Ord,- utf8Text,- utf8LazyText,- intercalate,- -- * Execution- length,- toByteString,- toLazyByteString,-)+ ( Builder,++ -- * Declaration++ -- ** Primitives+ byteString,+ byte,++ -- ** Extras+ asciiIntegral,+ asciiChar,+ utf8Char,+ utf8Ord,+ utf8Text,+ utf8LazyText,+ intercalate,++ -- * Execution+ length,+ toByteString,+ toLazyByteString,+ ) where -import ByteString.TreeBuilder.Prelude hiding (foldl, foldr, length, intercalate)-import qualified ByteString.TreeBuilder.Tree as A import qualified ByteString.TreeBuilder.Poker as D-import qualified ByteString.TreeBuilder.Prelude as F+import ByteString.TreeBuilder.Prelude hiding (foldl, foldr, intercalate, length)+import qualified ByteString.TreeBuilder.Tree as A import qualified Data.ByteString as B import qualified Data.ByteString.Internal as C import qualified Data.ByteString.Lazy.Internal as E import qualified Data.Text import qualified Data.Text.Lazy - -- | -- A binary-tree-based datastructure optimized for aggregation of bytestrings -- using the /O(1)/ appending operation.-data Builder =- Builder !Int !A.Tree+data Builder+ = Builder !Int !A.Tree -- | -- Implements `mappend` with /O(1)/ complexity.@@ -43,9 +44,6 @@ {-# INLINE mempty #-} mempty = Builder 0 A.Empty- {-# INLINABLE mappend #-}- mappend (Builder length1 tree1) (Builder length2 tree2) =- Builder (length1 + length2) (A.Branch tree1 tree2) {-# INLINE mconcat #-} mconcat = foldl' mappend mempty@@ -55,8 +53,9 @@ sconcat = foldl' mappend mempty - {-# INLINABLE (<>) #-}- (<>) = mappend+ {-# INLINEABLE (<>) #-}+ (Builder length1 tree1) <> (Builder length2 tree2) =+ Builder (length1 + length2) (A.Branch tree1 tree2) instance IsString Builder where {-# INLINE fromString #-}@@ -66,11 +65,12 @@ bytes = fromString string - -- * Declaration+ ------------------------- -- ** Primitives+ ------------------------- -- |@@ -88,18 +88,19 @@ Builder 1 (A.Leaf (B.singleton byte)) -- ** Extras+ ------------------------- -{-# INLINABLE asciiIntegral #-}-asciiIntegral :: Integral a => a -> Builder+{-# INLINEABLE asciiIntegral #-}+asciiIntegral :: (Integral a) => a -> Builder asciiIntegral = \case 0 -> byte 48 x ->- bool ((<>) (byte 45)) id (x >= 0) $- loop mempty $- abs x+ bool ((<>) (byte 45)) id (x >= 0)+ $ loop mempty+ $ abs x where loop builder remainder = case remainder of@@ -124,24 +125,23 @@ utf8Ord :: Int -> Builder utf8Ord x = if x <= 0x7F- then- byte (fromIntegral x)- else + then byte (fromIntegral x)+ else if x <= 0x07FF then- byte (fromIntegral ((x `shiftR` 6) + 0xC0)) <>- byte (fromIntegral ((x .&. 0x3F) + 0x80))+ byte (fromIntegral ((x `shiftR` 6) + 0xC0))+ <> byte (fromIntegral ((x .&. 0x3F) + 0x80)) else if x <= 0xFFFF then- byte (fromIntegral (x `shiftR` 12) + 0xE0) <>- byte (fromIntegral ((x `shiftR` 6) .&. 0x3F) + 0x80) <>- byte (fromIntegral (x .&. 0x3F) + 0x80)+ byte (fromIntegral (x `shiftR` 12) + 0xE0)+ <> byte (fromIntegral ((x `shiftR` 6) .&. 0x3F) + 0x80)+ <> byte (fromIntegral (x .&. 0x3F) + 0x80) else- byte (fromIntegral (x `shiftR` 18) + 0xF0) <>- byte (fromIntegral ((x `shiftR` 12) .&. 0x3F) + 0x80) <>- byte (fromIntegral ((x `shiftR` 6) .&. 0x3F) + 0x80) <>- byte (fromIntegral (x .&. 0x3F) + 0x80)+ byte (fromIntegral (x `shiftR` 18) + 0xF0)+ <> byte (fromIntegral ((x `shiftR` 12) .&. 0x3F) + 0x80)+ <> byte (fromIntegral ((x `shiftR` 6) .&. 0x3F) + 0x80)+ <> byte (fromIntegral (x .&. 0x3F) + 0x80) {-# INLINE utf8Text #-} utf8Text :: Data.Text.Text -> Builder@@ -153,22 +153,15 @@ utf8LazyText = Data.Text.Lazy.foldl' (\builder -> mappend builder . utf8Char) mempty -{-# INLINABLE intercalate #-}+{-# INLINEABLE intercalate #-} intercalate :: (Foldable f, Monoid m) => m -> f m -> m intercalate incut =- fst .- foldl' (\(acc, incutFn) x -> (incutFn (mappend x acc), mappend incut)) (mempty, id)-+ fst+ . foldl' (\(acc, incutFn) x -> (incutFn (mappend x acc), mappend incut)) (mempty, id) -- * Execution-------------------------- --- |--- Performs a left-fold over the aggregated chunks.-{-# INLINE foldl #-}-foldl :: (a -> ByteString -> a) -> a -> Builder -> a-foldl step init (Builder length tree) =- A.foldl step init tree+------------------------- -- | -- Performs a right-fold over the aggregated chunks.@@ -186,15 +179,15 @@ -- | -- /O(n)/. Converts the builder into a strict bytestring.-{-# INLINABLE toByteString #-}+{-# INLINEABLE toByteString #-} toByteString :: Builder -> ByteString toByteString (Builder length tree) =- C.unsafeCreate length $ \ptr -> + C.unsafeCreate length $ \ptr -> void $ D.pokeTree tree ptr -- | -- /O(n)/. Converts the builder into a lazy bytestring.-{-# INLINABLE toLazyByteString #-}+{-# INLINEABLE toLazyByteString #-} toLazyByteString :: Builder -> E.ByteString toLazyByteString = foldr E.Chunk E.Empty
library/ByteString/TreeBuilder/Poker.hs view
@@ -1,13 +1,11 @@ module ByteString.TreeBuilder.Poker where import ByteString.TreeBuilder.Prelude-import Foreign hiding (void)-import qualified Data.ByteString as A+import qualified ByteString.TreeBuilder.Tree as E import qualified Data.ByteString.Internal as B+import Foreign hiding (void) import qualified Foreign as D-import qualified ByteString.TreeBuilder.Tree as E - -- | -- Write the given bytes into the pointer and -- return a pointer incremented by the amount of written bytes.@@ -15,7 +13,7 @@ pokeBytes (B.PS foreignPointer offset length) pointer = do withForeignPtr foreignPointer $ \pointer' ->- B.memcpy pointer (plusPtr pointer' offset) length+ copyBytes pointer (plusPtr pointer' offset) length pure (plusPtr pointer length) -- |@@ -25,7 +23,7 @@ pokeBytesMinus (B.PS foreignPointer offset length) pointer = do withForeignPtr foreignPointer $ \pointer' ->- B.memcpy targetPointer (plusPtr pointer' offset) length+ copyBytes targetPointer (plusPtr pointer' offset) length pure targetPointer where targetPointer =
library/ByteString/TreeBuilder/Prelude.hs view
@@ -1,24 +1,26 @@ module ByteString.TreeBuilder.Prelude-( - module Exports,-)+ ( module Exports,+ ) where -- base --------------------------import Control.Applicative as Exports hiding (WrappedArrow(..))+import Control.Applicative as Exports hiding (WrappedArrow (..)) import Control.Arrow as Exports hiding (first, second) import Control.Category as Exports import Control.Concurrent as Exports import Control.Exception as Exports-import Control.Monad as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM)-import Control.Monad.IO.Class as Exports+import Control.Monad as Exports hiding (fail, forM, forM_, mapM, mapM_, msum, sequence, sequence_) import Control.Monad.Fail as Exports import Control.Monad.Fix as Exports hiding (fix)+import Control.Monad.IO.Class as Exports import Control.Monad.ST as Exports import Data.Bifunctor as Exports import Data.Bits as Exports import Data.Bool as Exports+-- bytestring+-------------------------+import Data.ByteString as Exports (ByteString) import Data.Char as Exports import Data.Coerce as Exports import Data.Complex as Exports@@ -28,20 +30,20 @@ import Data.Fixed as Exports import Data.Foldable as Exports hiding (toList) import Data.Function as Exports hiding (id, (.))-import Data.Functor as Exports+import Data.Functor as Exports hiding (unzip) import Data.Functor.Compose as Exports-import Data.Int as Exports import Data.IORef as Exports+import Data.Int as Exports import Data.Ix as Exports-import Data.List as Exports hiding (sortOn, isSubsequenceOf, uncons, concat, foldr, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, find, maximumBy, minimumBy, mapAccumL, mapAccumR, foldl')-import Data.List.NonEmpty as Exports (NonEmpty(..))+import Data.List as Exports hiding (all, and, any, concat, concatMap, elem, find, foldl, foldl', foldl1, foldr, foldr1, isSubsequenceOf, mapAccumL, mapAccumR, maximum, maximumBy, minimum, minimumBy, notElem, or, product, sortOn, sum, uncons)+import Data.List.NonEmpty as Exports (NonEmpty (..)) import Data.Maybe as Exports import Data.Monoid as Exports hiding (Alt, (<>)) import Data.Ord as Exports import Data.Proxy as Exports import Data.Ratio as Exports-import Data.Semigroup as Exports hiding (First(..), Last(..)) import Data.STRef as Exports+import Data.Semigroup as Exports hiding (First (..), Last (..)) import Data.String as Exports import Data.Traversable as Exports import Data.Tuple as Exports@@ -54,13 +56,12 @@ import Foreign.Ptr as Exports import Foreign.StablePtr as Exports import Foreign.Storable as Exports-import GHC.Conc as Exports hiding (orElse, withMVar, threadWaitWriteSTM, threadWaitWrite, threadWaitReadSTM, threadWaitRead)-import GHC.Exts as Exports (IsList(..), lazy, inline, sortWith, groupWith)+import GHC.Conc as Exports hiding (orElse, threadWaitRead, threadWaitReadSTM, threadWaitWrite, threadWaitWriteSTM, withMVar)+import GHC.Exts as Exports (IsList (..), groupWith, inline, lazy, sortWith) import GHC.Generics as Exports (Generic) import GHC.IO.Exception as Exports import GHC.OverloadedLabels as Exports import Numeric as Exports-import Prelude as Exports hiding (Read, fail, concat, foldr, mapM_, sequence_, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, mapM, sequence, id, (.)) import System.Environment as Exports import System.Exit as Exports import System.IO as Exports (Handle, hClose)@@ -70,10 +71,7 @@ import System.Mem.StableName as Exports import System.Timeout as Exports import Text.ParserCombinators.ReadP as Exports (ReadP, readP_to_S, readS_to_P)-import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readPrec_to_P, readP_to_Prec, readPrec_to_S, readS_to_Prec)-import Text.Printf as Exports (printf, hPrintf)+import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readP_to_Prec, readPrec_to_P, readPrec_to_S, readS_to_Prec)+import Text.Printf as Exports (hPrintf, printf) import Unsafe.Coerce as Exports---- bytestring---------------------------import Data.ByteString as Exports (ByteString)+import Prelude as Exports hiding (Read, all, and, any, concat, concatMap, elem, fail, foldl, foldl1, foldr, foldr1, id, mapM, mapM_, maximum, minimum, notElem, or, product, sequence, sequence_, sum, (.))
library/ByteString/TreeBuilder/Tree.hs view
@@ -1,18 +1,11 @@ module ByteString.TreeBuilder.Tree where -import ByteString.TreeBuilder.Prelude hiding (foldl, foldr, foldlM, length)-import qualified Data.ByteString as B-import qualified Data.ByteString.Internal as C-import qualified Data.ByteString.Lazy.Internal as E-import qualified ByteString.TreeBuilder.Prelude as F-import qualified Data.ByteString.Internal as G-import qualified Foreign as H-+import ByteString.TreeBuilder.Prelude hiding (foldl, foldlM, foldr, length) -data Tree =- Empty |- Leaf !ByteString |- Branch !Tree !Tree+data Tree+ = Empty+ | Leaf !ByteString+ | Branch !Tree !Tree {-# INLINE foldl #-} foldl :: (a -> ByteString -> a) -> a -> Tree -> a@@ -37,7 +30,7 @@ foldr step (foldr step init tree2) tree1 {-# INLINE foldlM #-}-foldlM :: Monad m => (a -> ByteString -> m a) -> a -> Tree -> m a+foldlM :: (Monad m) => (a -> ByteString -> m a) -> a -> Tree -> m a foldlM step init = \case Empty ->
tasty/Main.hs view
@@ -1,39 +1,38 @@ module Main where import BasePrelude hiding (assert)-import Test.QuickCheck.Instances+import ByteString.TreeBuilder+import qualified Data.ByteString.Lazy+import Test.QuickCheck.Instances () import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.QuickCheck-import ByteString.TreeBuilder-import qualified Data.ByteString.Lazy -+main :: IO () main = defaultMain tree +tree :: TestTree tree =- testGroup "All tests"- [- testProperty "Concatting a list of bytestrings is isomorphic to appending a list of builders (strict)" $- \bytestrings ->- mconcat bytestrings ===- toByteString (foldMap byteString bytestrings)- ,- testProperty "Concatting a list of bytestrings is isomorphic to appending a list of builders (lazy)" $- \bytestrings ->- mconcat bytestrings ===- Data.ByteString.Lazy.toStrict (toLazyByteString (foldMap byteString bytestrings))- ,- testCase "Regression (Issue #5)" $- let- fn name =- toByteString $- "FETCH FORWARD "- <> asciiIntegral 10- <> " FROM "- <> byteString name- in assertEqual ""- "FETCH FORWARD 10 FROM abc"- (fn "abc")- ]+ testGroup+ "All tests"+ [ testProperty "Concatting a list of bytestrings is isomorphic to appending a list of builders (strict)" $+ \bytestrings ->+ mconcat bytestrings+ === toByteString (foldMap byteString bytestrings),+ testProperty "Concatting a list of bytestrings is isomorphic to appending a list of builders (lazy)" $+ \bytestrings ->+ mconcat bytestrings+ === Data.ByteString.Lazy.toStrict (toLazyByteString (foldMap byteString bytestrings)),+ testCase "Regression (Issue #5)" $+ let fn name =+ toByteString $+ "FETCH FORWARD "+ <> asciiIntegral 10+ <> " FROM "+ <> byteString name+ in assertEqual+ ""+ "FETCH FORWARD 10 FROM abc"+ (fn "abc")+ ]