git.iko.soy/typeable/attoparsec
on master help sign in
Generalise the concat . reverse thing
commitb1c6694447321db82e5a41d36653fcb8dd8d97c9 authorBryan O'Sullivan <bos@serpentine.com> dateWed 22 Jul 2015, 11:28 (11 years ago) parent72a3e75
3 files changed+16−12
Data/Attoparsec/ByteString/Internal.hs+3−6 Data/Attoparsec/Internal.hs+10 Data/Attoparsec/Text/Internal.hs+3−6
Data/Attoparsec/ByteString/Internal.hs+3−6
@@ -257,7 +257,7 @@ takeTill p = takeWhile (not . p)
257257-- parsers loop until a failure occurs. Careless use will thus result
258258-- in an infinite loop.
259259takeWhile :: (Word8 -> Bool) -> Parser ByteString
260−takeWhile p = (B.concat . reverse) `fmap` go []
260+takeWhile p = concatReverse `fmap` go []
261261 where
262262 go acc = do
263263 s <- B8.takeWhile p <$> get
@@ -329,16 +329,13 @@ scan_ f s0 p = go [] s0
329329-- parsers loop until a failure occurs. Careless use will thus result
330330-- in an infinite loop.
331331scan :: s -> (s -> Word8 -> Maybe s) -> Parser ByteString
332−scan = scan_ $ \_ chunks ->
333− case chunks of
334− [x] -> return x
335− xs -> return $! B.concat $ reverse xs
332+scan = scan_ $ \_ chunks -> return $! concatReverse chunks
336333{-# INLINE scan #-}
337334
338335-- | Like 'scan', but generalized to return the final state of the
339336-- scanner.
340337runScanner :: s -> (s -> Word8 -> Maybe s) -> Parser (ByteString, s)
341−runScanner = scan_ $ \s xs -> return (B.concat (reverse xs), s)
338+runScanner = scan_ $ \s xs -> let !sx = concatReverse xs in return (sx, s)
342339{-# INLINE runScanner #-}
343340
344341-- | Consume input as long as the predicate returns 'True', and return
Data/Attoparsec/Internal.hs+10
@@ -20,10 +20,12 @@ module Data.Attoparsec.Internal
2020 , endOfInput
2121 , atEnd
2222 , satisfyElem
23+ , concatReverse
2324 ) where
2425
2526#if !MIN_VERSION_base(4,8,0)
2627import Control.Applicative ((<$>))
28+import Data.Monoid (Monoid, mconcat)
2729#endif
2830import Data.Attoparsec.Internal.Types
2931import Data.ByteString (ByteString)
@@ -159,3 +161,11 @@ satisfyElem p = Parser $ \t pos more lose succ ->
159161 | otherwise -> lose t pos more [] "satisfyElem"
160162 Nothing -> satisfySuspended p t pos more lose succ
161163{-# INLINE satisfyElem #-}
164+
165+-- | Concatenate a monoid after reversing its elements. Used to
166+-- glue together a series of textual chunks that have been accumulated
167+-- \"backwards\".
168+concatReverse :: Monoid m => [m] -> m
169+concatReverse [x] = x
170+concatReverse xs = mconcat (reverse xs)
171+{-# INLINE concatReverse #-}
Data/Attoparsec/Text/Internal.hs+3−6
@@ -269,7 +269,7 @@ takeTill p = takeWhile (not . p)
269269-- parsers loop until a failure occurs. Careless use will thus result
270270-- in an infinite loop.
271271takeWhile :: (Char -> Bool) -> Parser Text
272−takeWhile p = (T.concat . reverse) `fmap` go []
272+takeWhile p = concatReverse `fmap` go []
273273 where
274274 go acc = do
275275 h <- T.takeWhile p <$> get
@@ -334,16 +334,13 @@ scan_ f s0 p = go [] s0
334334-- parsers loop until a failure occurs. Careless use will thus result
335335-- in an infinite loop.
336336scan :: s -> (s -> Char -> Maybe s) -> Parser Text
337−scan = scan_ $ \_ chunks ->
338− case chunks of
339− [x] -> return x
340− xs -> return . T.concat . reverse $ xs
337+scan = scan_ $ \_ chunks -> return $! concatReverse chunks
341338{-# INLINE scan #-}
342339
343340-- | Like 'scan', but generalized to return the final state of the
344341-- scanner.
345342runScanner :: s -> (s -> Char -> Maybe s) -> Parser (Text, s)
346−runScanner = scan_ $ \s xs -> return (T.concat (reverse xs), s)
343+runScanner = scan_ $ \s xs -> let !sx = concatReverse xs in return (sx, s)
347344{-# INLINE runScanner #-}
348345
349346-- | Consume input as long as the predicate returns 'True', and return