git.iko.soy/typeable/attoparsec
on master help sign in
Generalise the concat . reverse thing
b1c6694Bryan O'Sullivan
Data/Attoparsec/ByteString/Internal.hs+3−6
@@ -257,7 +257,7 @@ takeTill p = takeWhile (not . p)
257-- parsers loop until a failure occurs. Careless use will thus result
257-- parsers loop until a failure occurs. Careless use will thus result
258-- in an infinite loop.
258-- in an infinite loop.
259takeWhile :: (Word8 -> Bool) -> Parser ByteString
259takeWhile :: (Word8 -> Bool) -> Parser ByteString
260−takeWhile p = (B.concat . reverse) `fmap` go []
260+takeWhile p = concatReverse `fmap` go []
261 where
261 where
262 go acc = do
262 go acc = do
263 s <- B8.takeWhile p <$> get
263 s <- B8.takeWhile p <$> get
@@ -329,16 +329,13 @@ scan_ f s0 p = go [] s0
329-- parsers loop until a failure occurs. Careless use will thus result
329-- parsers loop until a failure occurs. Careless use will thus result
330-- in an infinite loop.
330-- in an infinite loop.
331scan :: s -> (s -> Word8 -> Maybe s) -> Parser ByteString
331scan :: s -> (s -> Word8 -> Maybe s) -> Parser ByteString
332−scan = scan_ $ \_ chunks ->
332+scan = scan_ $ \_ chunks -> return $! concatReverse chunks
333− case chunks of
334− [x] -> return x
335− xs -> return $! B.concat $ reverse xs
336{-# INLINE scan #-}
333{-# INLINE scan #-}
337
334
338-- | Like 'scan', but generalized to return the final state of the
335-- | Like 'scan', but generalized to return the final state of the
339-- scanner.
336-- scanner.
340runScanner :: s -> (s -> Word8 -> Maybe s) -> Parser (ByteString, s)
337runScanner :: 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)
342{-# INLINE runScanner #-}
339{-# INLINE runScanner #-}
343
340
344-- | Consume input as long as the predicate returns 'True', and return
341-- | Consume input as long as the predicate returns 'True', and return
Data/Attoparsec/Internal.hs+10
@@ -20,10 +20,12 @@ module Data.Attoparsec.Internal
20 , endOfInput
20 , endOfInput
21 , atEnd
21 , atEnd
22 , satisfyElem
22 , satisfyElem
23+ , concatReverse
23 ) where
24 ) where
24
25
25#if !MIN_VERSION_base(4,8,0)
26#if !MIN_VERSION_base(4,8,0)
26import Control.Applicative ((<$>))
27import Control.Applicative ((<$>))
28+import Data.Monoid (Monoid, mconcat)
27#endif
29#endif
28import Data.Attoparsec.Internal.Types
30import Data.Attoparsec.Internal.Types
29import Data.ByteString (ByteString)
31import Data.ByteString (ByteString)
@@ -159,3 +161,11 @@ satisfyElem p = Parser $ \t pos more lose succ ->
159 | otherwise -> lose t pos more [] "satisfyElem"
161 | otherwise -> lose t pos more [] "satisfyElem"
160 Nothing -> satisfySuspended p t pos more lose succ
162 Nothing -> satisfySuspended p t pos more lose succ
161{-# INLINE satisfyElem #-}
163{-# 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)
269-- parsers loop until a failure occurs. Careless use will thus result
269-- parsers loop until a failure occurs. Careless use will thus result
270-- in an infinite loop.
270-- in an infinite loop.
271takeWhile :: (Char -> Bool) -> Parser Text
271takeWhile :: (Char -> Bool) -> Parser Text
272−takeWhile p = (T.concat . reverse) `fmap` go []
272+takeWhile p = concatReverse `fmap` go []
273 where
273 where
274 go acc = do
274 go acc = do
275 h <- T.takeWhile p <$> get
275 h <- T.takeWhile p <$> get
@@ -334,16 +334,13 @@ scan_ f s0 p = go [] s0
334-- parsers loop until a failure occurs. Careless use will thus result
334-- parsers loop until a failure occurs. Careless use will thus result
335-- in an infinite loop.
335-- in an infinite loop.
336scan :: s -> (s -> Char -> Maybe s) -> Parser Text
336scan :: s -> (s -> Char -> Maybe s) -> Parser Text
337−scan = scan_ $ \_ chunks ->
337+scan = scan_ $ \_ chunks -> return $! concatReverse chunks
338− case chunks of
339− [x] -> return x
340− xs -> return . T.concat . reverse $ xs
341{-# INLINE scan #-}
338{-# INLINE scan #-}
342
339
343-- | Like 'scan', but generalized to return the final state of the
340-- | Like 'scan', but generalized to return the final state of the
344-- scanner.
341-- scanner.
345runScanner :: s -> (s -> Char -> Maybe s) -> Parser (Text, s)
342runScanner :: 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)
347{-# INLINE runScanner #-}
344{-# INLINE runScanner #-}
348
345
349-- | Consume input as long as the predicate returns 'True', and return
346-- | Consume input as long as the predicate returns 'True', and return