cassava 0.4.5.1 → 0.5.0.0
raw patch · 14 files changed
+198/−384 lines, 14 filesdep +Onlydep +bytestring-builderdep +faildep −blaze-builderdep −criteriondep −lazy-csvdep ~HUnitdep ~QuickCheckdep ~arrayPVP ok
version bump matches the API change (PVP)
Dependencies added: Only, bytestring-builder, fail, semigroups, text-short
Dependencies removed: blaze-builder, criterion, lazy-csv
Dependency ranges changed: HUnit, QuickCheck, array, attoparsec, base, bytestring, containers, deepseq, hashable, test-framework, test-framework-hunit, test-framework-quickcheck2, text, unordered-containers, vector
API changes (from Hackage documentation)
+ Data.Csv.Incremental: instance Data.Semigroup.Semigroup (Data.Csv.Incremental.Builder a)
+ Data.Csv.Incremental: instance Data.Semigroup.Semigroup (Data.Csv.Incremental.NamedBuilder a)
- Data.Csv: newtype Only a
+ Data.Csv: newtype Only a :: * -> *
Files
- CHANGES.md +18/−0
- Data/Csv/Builder.hs +1/−1
- Data/Csv/Conversion.hs +33/−8
- Data/Csv/Conversion/Internal.hs +25/−18
- Data/Csv/Encoding.hs +17/−24
- Data/Csv/Incremental.hs +30/−13
- Data/Csv/Parser.hs +5/−6
- Data/Csv/Streaming.hs +1/−0
- Data/Csv/Util.hs +10/−0
- benchmarks/Benchmarks.hs +0/−156
- benchmarks/presidents.csv +0/−44
- benchmarks/presidents_with_header.csv +0/−45
- cassava.cabal +56/−68
- tests/UnitTests.hs +2/−1
CHANGES.md view
@@ -1,3 +1,21 @@+## Version 0.5.0.0++### Semantic changes++ * Don't unecessarily quote spaces with `QuoteMinimal` (#118,#122,#86)+ * Fix semantics of `foldl'` (#102)+ * Fix field error diagnostics being mapped to `endOfInput` in `Parser` monad. (#99)+ * Honor `encIncludeHeader` in incremental API (#136)++### Other changes++ * Support GHC 8.2.1+ * Use factored-out `Only` package+ * Add `FromField`/`ToField` instance for `ShortText`+ * Add `MonadFail` and `Semigroup` instance for `Parser`+ * Add `Semigroup` instance for incremental CSV API `Builder` & `NamedBuilder`+ * Port to `ByteString` builder & drop dependency on `blaze-builder`+ ## Version 0.4.5.1 * Restore GHC 7.4 support (#124)
Data/Csv/Builder.hs view
@@ -18,7 +18,7 @@ import Data.Monoid -import Blaze.ByteString.Builder as Builder+import Data.ByteString.Builder as Builder import Data.Csv.Conversion import qualified Data.Csv.Encoding as Encoding import Data.Csv.Encoding (EncodeOptions(..))
Data/Csv/Conversion.hs view
@@ -18,6 +18,14 @@ {-# LANGUAGE PolyKinds #-} #endif +#if !MIN_VERSION_bytestring(0,10,4)+# define MIN_VERSION_text_short(a,b,c) 0+#endif++#if !defined(MIN_VERSION_text_short)+# error **INVARIANT BROKEN** Detected invalid combination of `text-short` and `bytestring` versions. Please verify the `pre-bytestring-0.10-4` flag-logic in the .cabal file wasn't elided.+#endif+ module Data.Csv.Conversion ( -- * Type conversion@@ -49,6 +57,7 @@ import Control.Applicative (Alternative, (<|>), empty) import Control.Monad (MonadPlus, mplus, mzero)+import qualified Control.Monad.Fail as Fail import Data.Attoparsec.ByteString.Char8 (double) import qualified Data.Attoparsec.ByteString.Char8 as A8 import qualified Data.ByteString as B@@ -62,10 +71,15 @@ import Data.Int (Int8, Int16, Int32, Int64) import qualified Data.IntMap as IM import qualified Data.Map as M+import Data.Semigroup (Semigroup, (<>)) import qualified Data.Text as T import qualified Data.Text.Encoding as T import qualified Data.Text.Lazy as LT import qualified Data.Text.Lazy.Encoding as LT+#if MIN_VERSION_text_short(0,1,0)+import qualified Data.Text.Short as T.S+#endif+import Data.Tuple.Only (Only(..)) import Data.Vector (Vector, (!)) import qualified Data.Vector as V import qualified Data.Vector.Unboxed as U@@ -133,13 +147,6 @@ default parseRecord :: (Generic a, GFromRecord (Rep a)) => Record -> Parser a parseRecord r = to <$> gparseRecord r --- | Haskell lacks a single-element tuple type, so if you CSV data--- with just one column you can use the 'Only' type to represent a--- single-column result.-newtype Only a = Only {- fromOnly :: a- } deriving (Eq, Ord, Read, Show)- -- | A type that can be converted to a single CSV record. -- -- An example type and instance:@@ -872,6 +879,16 @@ {-# INLINE toField #-} #endif +#if MIN_VERSION_text_short(0,1,0)+instance FromField T.S.ShortText where+ parseField = maybe (fail "Invalid UTF-8 stream") pure . T.S.fromByteString+ {-# INLINE parseField #-}++instance ToField T.S.ShortText where+ toField = T.S.toByteString+ {-# INLINE toField #-}+#endif+ -- | Assumes UTF-8 encoding. Fails on invalid byte sequences. instance FromField T.Text where parseField = either (fail . show) pure . T.decodeUtf8'@@ -1037,6 +1054,10 @@ {-# INLINE (>>) #-} return = pure {-# INLINE return #-}+ fail = Fail.fail+ {-# INLINE fail #-}++instance Fail.MonadFail Parser where fail msg = Parser $ \kf _ks -> kf msg {-# INLINE fail #-} @@ -1064,10 +1085,14 @@ in unParser a kf' ks {-# INLINE mplus #-} +instance Semigroup (Parser a) where+ (<>) = mplus+ {-# INLINE (<>) #-}+ instance Monoid (Parser a) where mempty = fail "mempty" {-# INLINE mempty #-}- mappend = mplus+ mappend = (<>) {-# INLINE mappend #-} apP :: Parser (a -> b) -> Parser a -> Parser b
Data/Csv/Conversion/Internal.hs view
@@ -3,8 +3,9 @@ , realFloat ) where -import Blaze.ByteString.Builder-import Blaze.ByteString.Builder.Char8+import Data.ByteString.Builder (Builder, toLazyByteString, word8, char8,+ string8, byteString)+import qualified Data.ByteString.Builder.Prim as BP import Data.Array.Base (unsafeAt) import Data.Array.IArray import qualified Data.ByteString as B@@ -13,11 +14,13 @@ import Data.Monoid import Data.Word +import Data.Csv.Util (toStrict)+ ------------------------------------------------------------------------ -- Integers decimal :: Integral a => a -> B.ByteString-decimal = toByteString . formatDecimal+decimal = toStrict . toLazyByteString . formatDecimal {-# INLINE decimal #-} -- TODO: Add an optimized version for Integer.@@ -80,13 +83,13 @@ | otherwise = go (n `quot` 10) <> digit (n `rem` 10) minus :: Builder-minus = fromWord8 45+minus = word8 45 zero :: Word8 zero = 48 digit :: Integral a => a -> Builder-digit n = fromWord8 $! i2w (fromIntegral n)+digit n = word8 $! i2w (fromIntegral n) {-# INLINE digit #-} i2w :: Int -> Word8@@ -99,7 +102,7 @@ realFloat :: RealFloat a => a -> B.ByteString {-# SPECIALIZE realFloat :: Float -> B.ByteString #-} {-# SPECIALIZE realFloat :: Double -> B.ByteString #-}-realFloat = toByteString . formatRealFloat Generic+realFloat = toStrict . toLazyByteString . formatRealFloat Generic -- | Control the rendering of floating point numbers. data FPFormat = Exponent@@ -115,10 +118,10 @@ {-# SPECIALIZE formatRealFloat :: FPFormat -> Float -> Builder #-} {-# SPECIALIZE formatRealFloat :: FPFormat -> Double -> Builder #-} formatRealFloat fmt x- | isNaN x = fromString "NaN"+ | isNaN x = string8 "NaN" | isInfinite x = if x < 0- then fromString "-Infinity"- else fromString "Infinity"+ then string8 "-Infinity"+ else string8 "Infinity" | x < 0 || isNegativeZero x = minus <> doFmt fmt (floatToDigits (-x)) | otherwise = doFmt fmt (floatToDigits x) where@@ -131,23 +134,23 @@ Exponent -> let show_e' = formatDecimal (e-1) in case ds of- [48] -> fromString "0.0e0"- [d] -> fromWord8 d <> fromString ".0e" <> show_e'- (d:ds') -> fromWord8 d <> fromChar '.' <> fromWord8s ds' <>- fromChar 'e' <> show_e'+ [48] -> string8 "0.0e0"+ [d] -> word8 d <> string8 ".0e" <> show_e'+ (d:ds') -> word8 d <> char8 '.' <> word8s ds' <>+ char8 'e' <> show_e' [] -> error "formatRealFloat/doFmt/Exponent: []" Fixed- | e <= 0 -> fromString "0." <>- fromByteString (B.replicate (-e) zero) <>- fromWord8s ds+ | e <= 0 -> string8 "0." <>+ byteString (B.replicate (-e) zero) <>+ word8s ds | otherwise -> let- f 0 s rs = mk0 (reverse s) <> fromChar '.' <> mk0 rs+ f 0 s rs = mk0 (reverse s) <> char8 '.' <> mk0 rs f n s [] = f (n-1) (zero:s) [] f n s (r:rs) = f (n-1) (r:s) rs in f e [] ds- where mk0 ls = case ls of { [] -> fromWord8 zero ; _ -> fromWord8s ls}+ where mk0 ls = case ls of { [] -> word8 zero ; _ -> word8s ls} -- Based on "Printing Floating-Point Numbers Quickly and Accurately" -- by R.G. Burger and R.K. Dybvig in PLDI 96.@@ -283,3 +286,7 @@ {-# INLINE i2d #-} i2d :: Int -> Word8 i2d i = fromIntegral (ord '0' + i)++-- | Word8 list rendering+word8s :: [Word8] -> Builder+word8s = BP.primMapListFixed BP.word8
Data/Csv/Encoding.hs view
@@ -37,10 +37,8 @@ , recordSep ) where -import Blaze.ByteString.Builder (Builder, fromByteString, fromWord8,- toLazyByteString, toByteString)-import Blaze.ByteString.Builder.Char8 (fromString)-import Control.Applicative as AP (Applicative(..), (<|>), optional)+import Data.ByteString.Builder+import Control.Applicative as AP (Applicative(..), (<|>)) import Data.Attoparsec.ByteString.Char8 (endOfInput) import qualified Data.Attoparsec.ByteString.Lazy as AL import qualified Data.ByteString as B@@ -62,7 +60,7 @@ import qualified Data.Csv.Parser as Parser import Data.Csv.Types hiding (toNamedRecord) import qualified Data.Csv.Types as Types-import Data.Csv.Util (blankLine, endOfLine)+import Data.Csv.Util (blankLine, endOfLine, toStrict) -- TODO: 'encode' isn't as efficient as it could be.@@ -232,8 +230,8 @@ -- | Encode a single record, without the trailing record separator -- (i.e. newline). encodeRecord :: Quoting -> Word8 -> Record -> Builder-encodeRecord qtng delim = mconcat . intersperse (fromWord8 delim)- . map fromByteString . map (escape qtng delim) . V.toList+encodeRecord qtng delim = mconcat . intersperse (word8 delim)+ . map byteString . map (escape qtng delim) . V.toList {-# INLINE encodeRecord #-} -- | Encode a single named record, without the trailing record@@ -246,23 +244,22 @@ escape :: Quoting -> Word8 -> B.ByteString -> B.ByteString escape !qtng !delim !s | (qtng == QuoteMinimal &&- B.any (\ b -> b == dquote || b == delim || b == nl || b == cr || b == sp) s+ B.any (\ b -> b == dquote || b == delim || b == nl || b == cr) s ) || qtng == QuoteAll- = toByteString $- fromWord8 dquote+ = toStrict . toLazyByteString $+ word8 dquote <> B.foldl (\ acc b -> acc <> if b == dquote- then fromByteString "\"\""- else fromWord8 b)+ then byteString "\"\""+ else word8 b) mempty s- <> fromWord8 dquote+ <> word8 dquote | otherwise = s where dquote = 34 nl = 10 cr = 13- sp = 32 -- | Like 'encodeByName', but lets you customize how the CSV data is -- encoded.@@ -316,8 +313,8 @@ {-# NOINLINE moduleError #-} recordSep :: Bool -> Builder-recordSep False = fromWord8 10 -- new line (\n)-recordSep True = fromString "\r\n"+recordSep False = word8 10 -- new line (\n)+recordSep True = string8 "\r\n" unlines :: Builder -> [Builder] -> Builder unlines _ [] = mempty@@ -357,18 +354,16 @@ csv :: FromRecord a => DecodeOptions -> AL.Parser (V.Vector a) csv !opts = do vals <- records- _ <- optional endOfLine- endOfInput return $! V.fromList vals where records = do !r <- record (decDelimiter opts) if blankLine r- then (endOfLine *> records) <|> pure []+ then (endOfInput *> pure []) <|> (endOfLine *> records) else case runParser (parseRecord r) of Left msg -> fail $ "conversion error: " ++ msg Right val -> do- !vals <- (endOfLine *> records) <|> AP.pure []+ !vals <- (endOfInput *> AP.pure []) <|> (endOfLine *> records) return (val : vals) {-# INLINE csv #-} @@ -378,19 +373,17 @@ csvWithHeader !opts = do !hdr <- header (decDelimiter opts) vals <- records hdr- _ <- optional endOfLine- endOfInput let !v = V.fromList vals return (hdr, v) where records hdr = do !r <- record (decDelimiter opts) if blankLine r- then (endOfLine *> records hdr) <|> pure []+ then (endOfInput *> pure []) <|> (endOfLine *> records hdr) else case runParser (convert hdr r) of Left msg -> fail $ "conversion error: " ++ msg Right val -> do- !vals <- (endOfLine *> records hdr) <|> pure []+ !vals <- (endOfInput *> pure []) <|> (endOfLine *> records hdr) return (val : vals) convert hdr = parseNamedRecord . Types.toNamedRecord hdr
Data/Csv/Incremental.hs view
@@ -83,9 +83,9 @@ import qualified Data.Attoparsec.ByteString as A import Data.Attoparsec.ByteString.Char8 (endOfInput) import qualified Data.ByteString as B-import qualified Blaze.ByteString.Builder as Builder+import qualified Data.ByteString.Builder as Builder import qualified Data.ByteString.Lazy as L-import Data.Monoid ((<>))+import Data.Semigroup (Semigroup, (<>)) import qualified Data.Vector as V import Data.Word (Word8) @@ -344,12 +344,15 @@ runBuilder :: Quoting -> Word8 -> Bool -> Builder.Builder } -instance Monoid (Builder a) where- mempty = Builder (\ _ _ _ -> mempty)- mappend (Builder f) (Builder g) =+instance Semigroup (Builder a) where+ Builder f <> Builder g = Builder $ \ qtng delim useCrlf -> f qtng delim useCrlf <> g qtng delim useCrlf +instance Monoid (Builder a) where+ mempty = Builder (\ _ _ _ -> mempty)+ mappend = (<>)+ ------------------------------------------------------------------------ -- ** Index-based record conversion @@ -373,10 +376,15 @@ -> L.ByteString encodeByNameWith opts hdr b = Builder.toLazyByteString $- Encoding.encodeRecord (encQuoting opts) (encDelimiter opts) hdr <>- recordSep (encUseCrLf opts) <>+ encHdr <> runNamedBuilder b hdr (encQuoting opts) (encDelimiter opts) (encUseCrLf opts)+ where+ encHdr+ | encIncludeHeader opts =+ Encoding.encodeRecord (encQuoting opts) (encDelimiter opts) hdr+ <> recordSep (encUseCrLf opts)+ | otherwise = mempty -- | Like 'encodeDefaultOrderedByName', but lets you customize how the -- CSV data is encoded.@@ -385,12 +393,18 @@ EncodeOptions -> NamedBuilder a -> L.ByteString encodeDefaultOrderedByNameWith opts b = Builder.toLazyByteString $- Encoding.encodeRecord (encQuoting opts) (encDelimiter opts) hdr <>- recordSep (encUseCrLf opts) <>+ encHdr <> runNamedBuilder b hdr (encQuoting opts) (encDelimiter opts) (encUseCrLf opts)- where hdr = Conversion.headerOrder (undefined :: a)+ where+ hdr = Conversion.headerOrder (undefined :: a) + encHdr+ | encIncludeHeader opts =+ Encoding.encodeRecord (encQuoting opts) (encDelimiter opts) hdr+ <> recordSep (encUseCrLf opts)+ | otherwise = mempty+ -- | Encode a single named record. encodeNamedRecord :: ToNamedRecord a => a -> NamedBuilder a encodeNamedRecord nr = NamedBuilder $ \ hdr qtng delim useCrLf ->@@ -406,11 +420,14 @@ runNamedBuilder :: Header -> Quoting -> Word8 -> Bool -> Builder.Builder } -instance Monoid (NamedBuilder a) where- mempty = NamedBuilder (\ _ _ _ _ -> mempty)- mappend (NamedBuilder f) (NamedBuilder g) =+instance Semigroup (NamedBuilder a) where+ NamedBuilder f <> NamedBuilder g = NamedBuilder $ \ hdr qtng delim useCrlf -> f hdr qtng delim useCrlf <> g hdr qtng delim useCrlf++instance Monoid (NamedBuilder a) where+ mempty = NamedBuilder (\ _ _ _ _ -> mempty)+ mappend = (<>) ------------------------------------------------------------------------
Data/Csv/Parser.hs view
@@ -24,8 +24,7 @@ , field ) where -import Blaze.ByteString.Builder (fromByteString, toByteString)-import Blaze.ByteString.Builder.Char.Utf8 (fromChar)+import Data.ByteString.Builder (byteString, toLazyByteString, charUtf8) import Control.Applicative (optional) import Data.Attoparsec.ByteString.Char8 (char, endOfInput) import qualified Data.Attoparsec.ByteString as A@@ -37,7 +36,7 @@ import Data.Word (Word8) import Data.Csv.Types-import Data.Csv.Util ((<$!>), blankLine, endOfLine, liftM2', cr, newline, doubleQuote)+import Data.Csv.Util ((<$!>), blankLine, endOfLine, liftM2', cr, newline, doubleQuote, toStrict) #if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<$>), (*>), (<*), pure)@@ -177,16 +176,16 @@ dquote = char '"' unescape :: Z.Parser S.ByteString-unescape = toByteString <$!> go mempty where+unescape = (toStrict . toLazyByteString) <$!> go mempty where go acc = do h <- Z.takeWhile (/= doubleQuote) let rest = do start <- Z.take 2 if (S.unsafeHead start == doubleQuote && S.unsafeIndex start 1 == doubleQuote)- then go (acc `mappend` fromByteString h `mappend` fromChar '"')+ then go (acc `mappend` byteString h `mappend` charUtf8 '"') else fail "invalid CSV escape sequence" done <- Z.atEnd if done- then return (acc `mappend` fromByteString h)+ then return (acc `mappend` byteString h) else rest
Data/Csv/Streaming.hs view
@@ -115,6 +115,7 @@ foldlRecords' f = go where go z (Cons (Right x) rs) = let z' = f z x in z' `seq` go z' rs+ go z (Cons (Left _) rs) = go z rs go z _ = z {-# INLINE foldlRecords' #-} #endif
Data/Csv/Util.hs view
@@ -8,6 +8,7 @@ , doubleQuote , newline , cr+ , toStrict ) where import Control.Applicative ((<|>))@@ -20,6 +21,15 @@ #if !MIN_VERSION_base(4,8,0) import Control.Applicative ((*>))+#endif++#if MIN_VERSION_bytestring(0,10,0)+import Data.ByteString.Lazy (toStrict)+#else+import qualified Data.ByteString.Lazy as L++toStrict :: L.ByteString -> B.ByteString+toStrict = B.concat . L.toChunks #endif -- | A strict version of 'Data.Functor.<$>' for monads.
− benchmarks/Benchmarks.hs
@@ -1,156 +0,0 @@-{-# LANGUAGE BangPatterns, CPP, FlexibleInstances, OverloadedStrings,- RecordWildCards, TypeSynonymInstances #-}-{-# OPTIONS_GHC -funbox-strict-fields #-}--module Main ( main ) where--import Control.Applicative as AP-import Control.Exception (evaluate)-import Control.DeepSeq-import Criterion.Main-import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import qualified Data.ByteString.Lazy as BL-import qualified Data.HashMap.Strict as HM-import Control.Monad (mzero)-import Data.Text (Text)-import qualified Text.CSV.Lazy.ByteString as LazyCsv-import Data.Vector (Vector)-import qualified Data.Vector as V--import Data.Csv-import qualified Data.Csv.Streaming as Streaming--#if !MIN_VERSION_bytestring(0,10,0)-instance NFData (B.ByteString) where- rnf !s = ()-#endif--data President = President- { presidency :: !Int- , president :: !Text- , wikipediaEntry :: !ByteString- , tookOffice :: !ByteString- , leftOffice :: !ByteString- , party :: !Text- , homeState :: !Text- }--instance NFData President where- rnf (President {}) = ()--instance FromRecord President where- parseRecord v- | V.length v == 7 = President <$>- v .!! 0 AP.<*>- v .!! 1 <*>- v .!! 2 <*>- v .!! 3 <*>- v .!! 4 <*>- v .!! 5 <*>- v .!! 6- | otherwise = mzero---- | Unchecked version of '(.!)'.-(.!!) :: FromField a => Record -> Int -> Parser a-v .!! idx = parseField (V.unsafeIndex v idx)-{-# INLINE (.!!) #-}-infixl 9 .!!--instance ToRecord President where- toRecord (President {..}) =- record [toField presidency, toField president, toField wikipediaEntry,- toField tookOffice, toField leftOffice, toField party,- toField homeState]--instance FromNamedRecord President where- parseNamedRecord m = President <$>- m .: "Presidency" <*>- m .: "President" <*>- m .: "Wikipedia Entry" <*>- m .: "Took office" <*>- m .: "Left office" <*>- m .: "Party" <*>- m .: "Home State"--instance ToNamedRecord President where- toNamedRecord (President {..}) = namedRecord- [ "Presidency" .= presidency- , "President" .= president- , "Wikipedia Entry" .= wikipediaEntry- , "Took office" .= tookOffice- , "Left office" .= leftOffice- , "Party" .= party- , "Home State" .= homeState- ]--fromStrict :: B.ByteString -> BL.ByteString-fromStrict s = BL.fromChunks [s]--type BSHashMap a = HM.HashMap B.ByteString a--instance NFData LazyCsv.CSVField where- rnf LazyCsv.CSVField {} = ()- rnf LazyCsv.CSVFieldError {} = ()--instance NFData LazyCsv.CSVError where- rnf (LazyCsv.IncorrectRow !_ !_ !_ xs) = rnf xs- rnf (LazyCsv.BlankLine _ _ _ field) = rnf field- rnf (LazyCsv.FieldError field) = rnf field- rnf (LazyCsv.DuplicateHeader _ _ s) = rnf s- rnf LazyCsv.NoData = ()--main :: IO ()-main = do- !csvData <- fromStrict `fmap` B.readFile "benchmarks/presidents.csv"- !csvDataN <- fromStrict `fmap` B.readFile- "benchmarks/presidents_with_header.csv"- let (Right !presidents) = V.toList <$> decodePresidents csvData- (Right (!hdr, !presidentsNV)) = decodePresidentsN csvDataN- !presidentsN = V.toList presidentsNV- evaluate (rnf [presidents, presidentsN])- defaultMain [- bgroup "positional"- [ bgroup "decode"- [ bench "presidents/without conversion" $ whnf idDecode csvData- , bench "presidents/with conversion" $ whnf decodePresidents csvData- , bgroup "streaming"- [ bench "presidents/without conversion" $ nf idDecodeS csvData- , bench "presidents/with conversion" $ nf decodePresidentsS csvData- ]- ]- , bgroup "encode"- [ bench "presidents/with conversion" $ whnf encode presidents- ]- ]- , bgroup "named"- [ bgroup "decode"- [ bench "presidents/without conversion" $ whnf idDecodeN csvDataN- , bench "presidents/with conversion" $ whnf decodePresidentsN csvDataN- ]- , bgroup "encode"- [ bench "presidents/with conversion" $ whnf (encodeByName hdr) presidentsN- ]- ]- , bgroup "comparison"- [ bench "lazy-csv" $ nf LazyCsv.parseCSV csvData- ]- ]- where- decodePresidents :: BL.ByteString -> Either String (Vector President)- decodePresidents = decode NoHeader-- decodePresidentsN :: BL.ByteString -> Either String (Header, Vector President)- decodePresidentsN = decodeByName-- decodePresidentsS :: BL.ByteString -> Streaming.Records President- decodePresidentsS = Streaming.decode NoHeader-- idDecode :: BL.ByteString -> Either String (Vector (Vector B.ByteString))- idDecode = decode NoHeader-- idDecodeN :: BL.ByteString -> Either String (Header, Vector (BSHashMap B.ByteString))- idDecodeN = decodeByName-- idDecodeS :: BL.ByteString -> Streaming.Records (Vector B.ByteString)- idDecodeS = Streaming.decode NoHeader
− benchmarks/presidents.csv
@@ -1,44 +0,0 @@-1,George Washington,http://en.wikipedia.org/wiki/George_Washington,30/04/1789,04/03/1797,Independent,Virginia-2,John Adams,http://en.wikipedia.org/wiki/John_Adams,04/03/1797,04/03/1801,Federalist,Massachusetts-3,Thomas Jefferson,http://en.wikipedia.org/wiki/Thomas_Jefferson,04/03/1801,04/03/1809,Democratic-Republican,Virginia-4,James Madison,http://en.wikipedia.org/wiki/James_Madison,04/03/1809,04/03/1817,Democratic-Republican,Virginia-5,James Monroe,http://en.wikipedia.org/wiki/James_Monroe,04/03/1817,04/03/1825,Democratic-Republican,Virginia-6,John Quincy Adams,http://en.wikipedia.org/wiki/John_Quincy_Adams,04/03/1825,04/03/1829,Democratic-Republican/National Republican,Massachusetts-7,Andrew Jackson,http://en.wikipedia.org/wiki/Andrew_Jackson,04/03/1829,04/03/1837,Democratic,Tennessee-8,Martin Van Buren,http://en.wikipedia.org/wiki/Martin_Van_Buren,04/03/1837,04/03/1841,Democratic,New York-9,William Henry Harrison,http://en.wikipedia.org/wiki/William_Henry_Harrison,04/03/1841,04/04/1841,Whig,Ohio-10,John Tyler,http://en.wikipedia.org/wiki/John_Tyler,04/04/1841,04/03/1845,Whig,Virginia-11,James K. Polk,http://en.wikipedia.org/wiki/James_K._Polk,04/03/1845,04/03/1849,Democratic,Tennessee-12,Zachary Taylor,http://en.wikipedia.org/wiki/Zachary_Taylor,04/03/1849,09/07/1850,Whig,Louisiana-13,Millard Fillmore,http://en.wikipedia.org/wiki/Millard_Fillmore,09/07/1850,04/03/1853,Whig,New York-14,Franklin Pierce,http://en.wikipedia.org/wiki/Franklin_Pierce,04/03/1853,04/03/1857,Democratic,New Hampshire-15,James Buchanan,http://en.wikipedia.org/wiki/James_Buchanan,04/03/1857,04/03/1861,Democratic,Pennsylvania-16,Abraham Lincoln,http://en.wikipedia.org/wiki/Abraham_Lincoln,04/03/1861,15/04/1865,Republican/National Union,Illinois-17,Andrew Johnson,http://en.wikipedia.org/wiki/Andrew_Johnson,15/04/1865,04/03/1869,Democratic/National Union,Tennessee-18,Ulysses S. Grant,http://en.wikipedia.org/wiki/Ulysses_S._Grant,04/03/1869,04/03/1877,Republican,Ohio-19,Rutherford B. Hayes,http://en.wikipedia.org/wiki/Rutherford_B._Hayes,04/03/1877,04/03/1881,Republican,Ohio-20,James A. Garfield,http://en.wikipedia.org/wiki/James_A._Garfield,04/03/1881,19/09/1881,Republican,Ohio-21,Chester A. Arthur,http://en.wikipedia.org/wiki/Chester_A._Arthur,19/09/1881,04/03/1885,Republican,New York-22,Grover Cleveland,http://en.wikipedia.org/wiki/Grover_Cleveland,04/03/1885,04/03/1889,Democratic,New York-23,Benjamin Harrison,http://en.wikipedia.org/wiki/Benjamin_Harrison,04/03/1889,04/03/1893,Republican,Indiana-24,Grover Cleveland (2nd term),http://en.wikipedia.org/wiki/Grover_Cleveland,04/03/1893,04/03/1897,Democratic,New York-25,William McKinley,http://en.wikipedia.org/wiki/William_McKinley,04/03/1897,14/09/1901,Republican,Ohio-26,Theodore Roosevelt,http://en.wikipedia.org/wiki/Theodore_Roosevelt,14/09/1901,04/03/1909,Republican,New York-27,William Howard Taft,http://en.wikipedia.org/wiki/William_Howard_Taft,04/03/1909,04/03/1913,Republican,Ohio-28,Woodrow Wilson,http://en.wikipedia.org/wiki/Woodrow_Wilson,04/03/1913,04/03/1921,Democratic,New Jersey-29,Warren G. Harding,http://en.wikipedia.org/wiki/Warren_G._Harding,04/03/1921,02/08/1923,Republican,Ohio-30,Calvin Coolidge,http://en.wikipedia.org/wiki/Calvin_Coolidge,02/08/1923,04/03/1929,Republican,Massachusetts-31,Herbert Hoover,http://en.wikipedia.org/wiki/Herbert_Hoover,04/03/1929,04/03/1933,Republican,Iowa-32,Franklin D. Roosevelt,http://en.wikipedia.org/wiki/Franklin_D._Roosevelt,04/03/1933,12/04/1945,Democratic,New York-33,Harry S. Truman,http://en.wikipedia.org/wiki/Harry_S._Truman,12/04/1945,20/01/1953,Democratic,Missouri-34,Dwight D. Eisenhower,http://en.wikipedia.org/wiki/Dwight_D._Eisenhower,20/01/1953,20/01/1961,Republican,Texas-35,John F. Kennedy,http://en.wikipedia.org/wiki/John_F._Kennedy,20/01/1961,22/11/1963,Democratic,Massachusetts-36,Lyndon B. Johnson,http://en.wikipedia.org/wiki/Lyndon_B._Johnson,22/11/1963,20/01/1969,Democratic,Texas-37,Richard Nixon,http://en.wikipedia.org/wiki/Richard_Nixon,20/01/1969,09/08/1974,Republican,California-38,Gerald Ford,http://en.wikipedia.org/wiki/Gerald_Ford,09/08/1974,20/01/1977,Republican,Michigan-39,Jimmy Carter,http://en.wikipedia.org/wiki/Jimmy_Carter,20/01/1977,20/01/1981,Democratic,Georgia-40,Ronald Reagan,http://en.wikipedia.org/wiki/Ronald_Reagan,20/01/1981,20/01/1989,Republican,California-41,George H. W. Bush,http://en.wikipedia.org/wiki/George_H._W._Bush,20/01/1989,20/01/1993,Republican,Texas-42,Bill Clinton,http://en.wikipedia.org/wiki/Bill_Clinton,20/01/1993,20/01/2001,Democratic,Arkansas-43,George W. Bush,http://en.wikipedia.org/wiki/George_W._Bush,20/01/2001,20/01/2009,Republican,Texas-44,Barack Obama,http://en.wikipedia.org/wiki/Barack_Obama,20/01/2009,Incumbent, Democratic ,Illinois
− benchmarks/presidents_with_header.csv
@@ -1,45 +0,0 @@-Presidency,President,Wikipedia Entry,Took office,Left office,Party,Home State-1,George Washington,http://en.wikipedia.org/wiki/George_Washington,30/04/1789,04/03/1797,Independent,Virginia-2,John Adams,http://en.wikipedia.org/wiki/John_Adams,04/03/1797,04/03/1801,Federalist,Massachusetts-3,Thomas Jefferson,http://en.wikipedia.org/wiki/Thomas_Jefferson,04/03/1801,04/03/1809,Democratic-Republican,Virginia-4,James Madison,http://en.wikipedia.org/wiki/James_Madison,04/03/1809,04/03/1817,Democratic-Republican,Virginia-5,James Monroe,http://en.wikipedia.org/wiki/James_Monroe,04/03/1817,04/03/1825,Democratic-Republican,Virginia-6,John Quincy Adams,http://en.wikipedia.org/wiki/John_Quincy_Adams,04/03/1825,04/03/1829,Democratic-Republican/National Republican,Massachusetts-7,Andrew Jackson,http://en.wikipedia.org/wiki/Andrew_Jackson,04/03/1829,04/03/1837,Democratic,Tennessee-8,Martin Van Buren,http://en.wikipedia.org/wiki/Martin_Van_Buren,04/03/1837,04/03/1841,Democratic,New York-9,William Henry Harrison,http://en.wikipedia.org/wiki/William_Henry_Harrison,04/03/1841,04/04/1841,Whig,Ohio-10,John Tyler,http://en.wikipedia.org/wiki/John_Tyler,04/04/1841,04/03/1845,Whig,Virginia-11,James K. Polk,http://en.wikipedia.org/wiki/James_K._Polk,04/03/1845,04/03/1849,Democratic,Tennessee-12,Zachary Taylor,http://en.wikipedia.org/wiki/Zachary_Taylor,04/03/1849,09/07/1850,Whig,Louisiana-13,Millard Fillmore,http://en.wikipedia.org/wiki/Millard_Fillmore,09/07/1850,04/03/1853,Whig,New York-14,Franklin Pierce,http://en.wikipedia.org/wiki/Franklin_Pierce,04/03/1853,04/03/1857,Democratic,New Hampshire-15,James Buchanan,http://en.wikipedia.org/wiki/James_Buchanan,04/03/1857,04/03/1861,Democratic,Pennsylvania-16,Abraham Lincoln,http://en.wikipedia.org/wiki/Abraham_Lincoln,04/03/1861,15/04/1865,Republican/National Union,Illinois-17,Andrew Johnson,http://en.wikipedia.org/wiki/Andrew_Johnson,15/04/1865,04/03/1869,Democratic/National Union,Tennessee-18,Ulysses S. Grant,http://en.wikipedia.org/wiki/Ulysses_S._Grant,04/03/1869,04/03/1877,Republican,Ohio-19,Rutherford B. Hayes,http://en.wikipedia.org/wiki/Rutherford_B._Hayes,04/03/1877,04/03/1881,Republican,Ohio-20,James A. Garfield,http://en.wikipedia.org/wiki/James_A._Garfield,04/03/1881,19/09/1881,Republican,Ohio-21,Chester A. Arthur,http://en.wikipedia.org/wiki/Chester_A._Arthur,19/09/1881,04/03/1885,Republican,New York-22,Grover Cleveland,http://en.wikipedia.org/wiki/Grover_Cleveland,04/03/1885,04/03/1889,Democratic,New York-23,Benjamin Harrison,http://en.wikipedia.org/wiki/Benjamin_Harrison,04/03/1889,04/03/1893,Republican,Indiana-24,Grover Cleveland (2nd term),http://en.wikipedia.org/wiki/Grover_Cleveland,04/03/1893,04/03/1897,Democratic,New York-25,William McKinley,http://en.wikipedia.org/wiki/William_McKinley,04/03/1897,14/09/1901,Republican,Ohio-26,Theodore Roosevelt,http://en.wikipedia.org/wiki/Theodore_Roosevelt,14/09/1901,04/03/1909,Republican,New York-27,William Howard Taft,http://en.wikipedia.org/wiki/William_Howard_Taft,04/03/1909,04/03/1913,Republican,Ohio-28,Woodrow Wilson,http://en.wikipedia.org/wiki/Woodrow_Wilson,04/03/1913,04/03/1921,Democratic,New Jersey-29,Warren G. Harding,http://en.wikipedia.org/wiki/Warren_G._Harding,04/03/1921,02/08/1923,Republican,Ohio-30,Calvin Coolidge,http://en.wikipedia.org/wiki/Calvin_Coolidge,02/08/1923,04/03/1929,Republican,Massachusetts-31,Herbert Hoover,http://en.wikipedia.org/wiki/Herbert_Hoover,04/03/1929,04/03/1933,Republican,Iowa-32,Franklin D. Roosevelt,http://en.wikipedia.org/wiki/Franklin_D._Roosevelt,04/03/1933,12/04/1945,Democratic,New York-33,Harry S. Truman,http://en.wikipedia.org/wiki/Harry_S._Truman,12/04/1945,20/01/1953,Democratic,Missouri-34,Dwight D. Eisenhower,http://en.wikipedia.org/wiki/Dwight_D._Eisenhower,20/01/1953,20/01/1961,Republican,Texas-35,John F. Kennedy,http://en.wikipedia.org/wiki/John_F._Kennedy,20/01/1961,22/11/1963,Democratic,Massachusetts-36,Lyndon B. Johnson,http://en.wikipedia.org/wiki/Lyndon_B._Johnson,22/11/1963,20/01/1969,Democratic,Texas-37,Richard Nixon,http://en.wikipedia.org/wiki/Richard_Nixon,20/01/1969,09/08/1974,Republican,California-38,Gerald Ford,http://en.wikipedia.org/wiki/Gerald_Ford,09/08/1974,20/01/1977,Republican,Michigan-39,Jimmy Carter,http://en.wikipedia.org/wiki/Jimmy_Carter,20/01/1977,20/01/1981,Democratic,Georgia-40,Ronald Reagan,http://en.wikipedia.org/wiki/Ronald_Reagan,20/01/1981,20/01/1989,Republican,California-41,George H. W. Bush,http://en.wikipedia.org/wiki/George_H._W._Bush,20/01/1989,20/01/1993,Republican,Texas-42,Bill Clinton,http://en.wikipedia.org/wiki/Bill_Clinton,20/01/1993,20/01/2001,Democratic,Arkansas-43,George W. Bush,http://en.wikipedia.org/wiki/George_W._Bush,20/01/2001,20/01/2009,Republican,Texas-44,Barack Obama,http://en.wikipedia.org/wiki/Barack_Obama,20/01/2009,Incumbent, Democratic ,Illinois
cassava.cabal view
@@ -1,5 +1,5 @@ Name: cassava-Version: 0.4.5.1+Version: 0.5.0.0 Synopsis: A CSV parsing and encoding library Description: A CSV parsing and encoding library optimized for ease of use and high@@ -16,11 +16,15 @@ Category: Text, Web, CSV Build-type: Simple Cabal-version: >=1.10-Extra-source-files: benchmarks/*.csv,- examples/*.hs,+Extra-source-files: examples/*.hs, CHANGES.md-Tested-with: GHC ==8.0.1, GHC ==7.10.3, GHC ==7.8.4, GHC ==7.6.3, GHC ==7.4.2+Tested-with: GHC ==8.2.1, GHC ==8.0.2, GHC ==8.0.1, GHC ==7.10.3, GHC ==7.8.4, GHC ==7.6.3, GHC ==7.4.2 +----------------------------------------------------------------------------++flag pre-bytestring-0-10-4+ description: bytestring < 0.10.4+ Library default-language: Haskell2010 other-extensions:@@ -60,90 +64,74 @@ Data.Csv.Util Build-depends:- array < 0.6,+ array >= 0.4 && < 0.6, attoparsec >= 0.10.2 && < 0.14, base >= 4.5 && < 5,- blaze-builder < 0.5,- bytestring < 0.11,- containers < 0.6,+ bytestring >= 0.9.2 && < 0.11,+ containers >= 0.4.2 && < 0.6, deepseq >= 1.1 && < 1.5, hashable < 1.3, text < 1.3, unordered-containers < 0.3,- vector < 0.12+ vector >= 0.8 && < 0.13,+ Only >= 0.1 && < 0.1.1 + if flag(pre-bytestring-0-10-4)+ build-depends: bytestring < 0.10.4+ , bytestring-builder >= 0.10.8 && < 0.11+ else+ build-depends: bytestring >= 0.10.4+ , text-short == 0.1.*+ -- GHC.Generics lived in `ghc-prim` for GHC 7.2 & GHC 7.4 only if impl(ghc < 7.6) build-depends: ghc-prim == 0.2.* + -- https://ghc.haskell.org/trac/ghc/wiki/Migration/8.0#Recommendationsforforward-compatibility+ if impl(ghc >= 8.0)+ ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances+ else+ -- provide/emulate `Control.Monad.Fail` and `Data.Semigroups` API for pre-GHC8+ build-depends: fail == 4.9.*, semigroups == 0.18.*++ if impl(ghc >= 8.2)+ ghc-options: -Wcpp-undef+ ghc-options: -Wall -O2 +----------------------------------------------------------------------------+ Test-suite unit-tests default-language: Haskell2010 Type: exitcode-stdio-1.0 Main-is: UnitTests.hs- Build-depends:- attoparsec,- base >= 4.5,- bytestring,- cassava,- hashable < 1.3,- HUnit,- QuickCheck >= 2.0,- test-framework,- test-framework-hunit,- test-framework-quickcheck2,- text,- unordered-containers,- vector+ -- dependencies with version constraints inherited via lib:cassava+ Build-depends: attoparsec+ , base+ , bytestring+ , cassava+ , hashable+ , text+ , unordered-containers+ , vector+ -- extra dependencies not already used by lib:cassava+ build-depends: HUnit < 1.7+ , QuickCheck == 2.10.*+ , test-framework == 0.8.*+ , test-framework-hunit == 0.3.*+ , test-framework-quickcheck2 == 0.3.* hs-source-dirs: tests- ghc-options: -Wall -Benchmark benchmarks- default-language: Haskell2010-- Type: exitcode-stdio-1.0- Main-is: Benchmarks.hs-- Other-modules:- Data.Csv- Data.Csv.Conversion- Data.Csv.Conversion.Internal- Data.Csv.Encoding- Data.Csv.Incremental- Data.Csv.Parser- Data.Csv.Streaming- Data.Csv.Types- Data.Csv.Util-- Build-depends:- array < 0.6,- attoparsec >= 0.10.2 && < 0.14,- base >= 4.5 && < 5,- blaze-builder < 0.5,- bytestring < 0.11,- containers < 0.6,- criterion >= 1.0,- deepseq < 1.5,- hashable < 1.3,- lazy-csv >= 0.5,- text < 1.3,- text,- unordered-containers < 0.3,- vector < 0.12-- -- GHC.Generics lived in `ghc-prim` for GHC 7.2 & GHC 7.4 only- if impl(ghc < 7.6)- build-depends: ghc-prim == 0.2.*-- ghc-options: -Wall -O2+ -- https://ghc.haskell.org/trac/ghc/wiki/Migration/8.0#Recommendationsforforward-compatibility+ if impl(ghc >= 8.0)+ ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances+ else+ -- provide/emulate `Control.Monad.Fail` and `Data.Semigroups` API for pre-GHC8+ build-depends: fail == 4.9.*, semigroups == 0.18.* - -- We cannot depend on the library directly as that creates a- -- dependency cycle.- hs-source-dirs: . benchmarks+ if impl(ghc >= 8.2)+ ghc-options: -Wcpp-undef -source-repository head- type: git- location: https://github.com/hvr/cassava.git+ ghc-options: -Wall
tests/UnitTests.hs view
@@ -111,7 +111,7 @@ , ("quoted", [["\"abc\""]], "\"\"\"abc\"\"\"\r\n") , ("quote", [["a\"b"]], "\"a\"\"b\"\r\n") , ("quotedQuote", [["\"a\"b\""]], "\"\"\"a\"\"b\"\"\"\r\n")- , ("leadingSpace", [[" abc"]], "\" abc\"\r\n")+ , ("leadingSpace", [[" abc"]], " abc\r\n") , ("comma", [["abc,def"]], "\"abc,def\"\r\n") , ("twoFields", [["abc","def"]], "abc,def\r\n") , ("twoRecords", [["abc"], ["def"]], "abc\r\ndef\r\n")@@ -370,6 +370,7 @@ [ testGroup "Records instances" [ testCase "foldr Foldable" (expected @=? F.foldr (:) [] input)+ , testCase "foldl' Foldable" (expected @=? F.foldl' (flip (:)) [] input) ] ] where