on master help sign in
Fix takeEQ

takeEQ was not terminating promptly, it was holding up the output till the next input even though it could have terminated earlier.

commitdea4c4eedbf1f97e93b8ef07339d8a12fc563261 authorHarendra Kumar <harendra@composewell.com> dateSun 6 Dec 2020, 19:56 (6 years ago) parent425adca
2 files changed+25−11
src/Streamly/Internal/Data/Parser.hs+3−2 src/Streamly/Internal/Data/Parser/ParserD.hs+22−9
src/Streamly/Internal/Data/Parser.hs+3−2
@@ -408,8 +408,9 @@ take n = K.toParserK . D.take n
408408
409409-- | Stops after taking exactly @n@ input elements.
410410--
411−-- * Stops - after @n@ elements.
412−-- * Fails - if the stream ends before it can collect @n@ elements.
411+-- * Stops - after consuming @n@ elements.
412+-- * Fails - if the stream or the collecting fold ends before it can collect
413+-- exactly @n@ elements.
413414--
414415-- >>> S.parse (PR.takeEQ 4 FL.toList) $ S.fromList [1,0,1]
415416-- > "takeEQ: Expecting exactly 4 elements, got 3"
src/Streamly/Internal/Data/Parser/ParserD.hs+22−9
@@ -310,7 +310,6 @@ either parser = Parser step initial extract
310310take :: Monad m => Int -> Fold m a b -> Parser m a b
311311take n fld = fromFold $ FL.ltake n fld
312312
313−-- XXX We are purposefully ignoring the input here
314313-- | See 'Streamly.Internal.Data.Parser.takeEQ'.
315314--
316315-- /Internal/
@@ -326,21 +325,35 @@ takeEQ cnt (Fold fstep finitial fextract) = Parser step initial extract
326325 initial = Tuple' 0 <$> finitial
327326
328327 step (Tuple' i r) a
329− | i < n = do
328+ | i1 < n = do
330329 res <- fstep r a
331330 return
332331 $ case res of
333− FL.Partial s -> Continue 0 $ Tuple' (i + 1) s
334− FL.Done _ -> Error $ err (i + 1)
332+ FL.Partial s -> Continue 0 $ Tuple' i1 s
333+ FL.Done _ ->
334+ Error
335+ $ "takeEQ: the collecting fold terminated after "
336+ ++ "consuming" ++ show i1 ++ " elements"
337+ | i1 == n = do
338+ res <- fstep r a
339+ Done 0
340+ <$> case res of
341+ FL.Partial s -> fextract s
342+ FL.Done b -> return b
343+ -- reachable only when n == 0
335344 | otherwise = Done 1 <$> fextract r
336345
337− extract (Tuple' i r)
338− | i == n = fextract r
339− | otherwise = throwM $ ParseError $ err i
346+ where
340347
341− err i =
342− "takeEQ: Expecting exactly " ++ show n ++ " elements, got " ++ show i
348+ i1 = i + 1
343349
350+ extract (Tuple' i r)
351+ | i == 0 && n == 0 = fextract r
352+ | otherwise =
353+ throwM
354+ $ ParseError
355+ $ "takeEQ: Expecting exactly "
356+ ++ show n ++ " elements, got " ++ show i
344357
345358-- | See 'Streamly.Internal.Data.Parser.takeGE'.
346359--