git.iko.soy/typeable/attoparsec
on master help sign in
Generalize scan on ByteString to runScanner

The name is by analogy to State. The issue is gh-8. --HG-- extra : amend_source : a1245546da829cb23416074cfbe613e7fbb7b31d

commit4624b0b54275f2b930a7aa5020d9443540deb2e1 authorBryan O'Sullivan <bos@serpentine.com> dateFri 14 Feb 2014, 17:20 (13 years ago) parent0c33039
1 file changed+30−19
Data/Attoparsec/ByteString/Internal.hs+30−19
Data/Attoparsec/ByteString/Internal.hs+30−19
@@ -50,6 +50,7 @@ module Data.Attoparsec.ByteString.Internal
5050 , stringTransform
5151 , take
5252 , scan
53+ , runScanner
5354 , takeWhile
5455 , takeWhile1
5556 , takeTill
@@ -246,23 +247,9 @@ takeLazyByteString = L.fromChunks `fmap` takeRest
246247
247248data T s = T {-# UNPACK #-} !Int s
248249
249−-- | A stateful scanner. The predicate consumes and transforms a
250−-- state argument, and each transformed state is passed to successive
251−-- invocations of the predicate on each byte of the input until one
252−-- returns 'Nothing' or the input ends.
253−--
254−-- This parser does not fail. It will return an empty string if the
255−-- predicate returns 'Nothing' on the first byte of input.
256−--
257−-- /Note/: Because this parser does not fail, do not use it with
258−-- combinators such as 'many', because such parsers loop until a
259−-- failure occurs. Careless use will thus result in an infinite loop.
260−scan :: s -> (s -> Word8 -> Maybe s) -> Parser B.ByteString
261−scan s0 p = do
262− chunks <- go [] s0
263− case chunks of
264− [x] -> return x
265− xs -> return $! B.concat $ reverse xs
250+scan_ :: (s -> [B.ByteString] -> Parser r) -> s -> (s -> Word8 -> Maybe s)
251+ -> Parser r
252+scan_ f s0 p = go [] s0
266253 where
267254 go acc s1 = do
268255 let scanner (B.PS fp off len) =
@@ -288,10 +275,34 @@ scan s0 p = do
288275 input <- wantInput
289276 if input
290277 then go (h:acc) s'
291− else return (h:acc)
292− else return (h:acc)
278+ else f s' (h:acc)
279+ else f s' (h:acc)
280+{-# INLINE scan_ #-}
281+
282+-- | A stateful scanner. The predicate consumes and transforms a
283+-- state argument, and each transformed state is passed to successive
284+-- invocations of the predicate on each byte of the input until one
285+-- returns 'Nothing' or the input ends.
286+--
287+-- This parser does not fail. It will return an empty string if the
288+-- predicate returns 'Nothing' on the first byte of input.
289+--
290+-- /Note/: Because this parser does not fail, do not use it with
291+-- combinators such as 'many', because such parsers loop until a
292+-- failure occurs. Careless use will thus result in an infinite loop.
293+scan :: s -> (s -> Word8 -> Maybe s) -> Parser B.ByteString
294+scan = scan_ $ \_ chunks ->
295+ case chunks of
296+ [x] -> return x
297+ xs -> return $! B.concat $ reverse xs
293298{-# INLINE scan #-}
294299
300+-- | Like 'scan', but generalized to return the final state of the
301+-- scanner.
302+runScanner :: s -> (s -> Word8 -> Maybe s) -> Parser (B.ByteString, s)
303+runScanner = scan_ $ \s xs -> return (B.concat (reverse xs), s)
304+{-# INLINE runScanner #-}
305+
295306-- | Consume input as long as the predicate returns 'True', and return
296307-- the consumed input.
297308--