Remove redundant parsers, update docs

Remove the parsers that are covered by terminating folds.
This commit is contained in:
Harendra Kumar 2020-12-10 20:18:26 +00:00
parent 82efd3a5bc
commit d5af0bfb5d
10 changed files with 227 additions and 538 deletions

View File

@ -15,6 +15,7 @@ module Main
import Control.DeepSeq (NFData(..)) import Control.DeepSeq (NFData(..))
import Control.Monad.Catch (MonadCatch) import Control.Monad.Catch (MonadCatch)
import Data.Foldable (asum) import Data.Foldable (asum)
import Data.Functor (($>))
import Data.Monoid (Sum(..)) import Data.Monoid (Sum(..))
import System.Random (randomRIO) import System.Random (randomRIO)
import Prelude import Prelude
@ -59,22 +60,14 @@ benchIOSink value name f =
-- Parsers -- Parsers
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
{-# INLINE any #-}
any :: (MonadCatch m, Ord a) => a -> SerialT m a -> m Bool
any value = IP.parse (PR.any (> value))
{-# INLINE all #-}
all :: (MonadCatch m, Ord a) => a -> SerialT m a -> m Bool
all value = IP.parse (PR.all (<= value))
{-# INLINE take #-}
take :: MonadCatch m => Int -> SerialT m a -> m ()
take value = IP.parse (PR.take value FL.drain)
{-# INLINE takeEQ #-} {-# INLINE takeEQ #-}
takeEQ :: MonadCatch m => Int -> SerialT m a -> m () takeEQ :: MonadCatch m => Int -> SerialT m a -> m ()
takeEQ value = IP.parse (PR.takeEQ value FL.drain) takeEQ value = IP.parse (PR.takeEQ value FL.drain)
{-# INLINE drainWhile #-}
drainWhile :: MonadCatch m => Int -> SerialT m Int -> m ()
drainWhile value = IP.parse (PR.drainWhile (<= value))
{-# INLINE takeWhile #-} {-# INLINE takeWhile #-}
takeWhile :: MonadCatch m => Int -> SerialT m Int -> m () takeWhile :: MonadCatch m => Int -> SerialT m Int -> m ()
takeWhile value = IP.parse (PR.takeWhile (<= value) FL.drain) takeWhile value = IP.parse (PR.takeWhile (<= value) FL.drain)
@ -106,57 +99,91 @@ manyTill value =
{-# INLINE splitAp #-} {-# INLINE splitAp #-}
splitAp :: MonadCatch m splitAp :: MonadCatch m
=> Int -> SerialT m Int -> m (Bool, Bool) => Int -> SerialT m Int -> m ((), ())
splitAp value = splitAp value =
IP.parse ((,) <$> PR.all (<= (value `div` 2)) <*> PR.any (> value)) IP.parse
((,)
<$> PR.drainWhile (<= (value `div` 2))
<*> PR.drainWhile (<= value)
)
{-# INLINE splitApBefore #-} {-# INLINE splitApBefore #-}
splitApBefore :: MonadCatch m splitApBefore :: MonadCatch m
=> Int -> SerialT m Int -> m Bool => Int -> SerialT m Int -> m ()
splitApBefore value = splitApBefore value =
IP.parse (PR.all (<= (value `div` 2)) *> PR.any (> value)) IP.parse
( PR.drainWhile (<= (value `div` 2))
*> PR.drainWhile (<= value)
)
{-# INLINE splitApAfter #-} {-# INLINE splitApAfter #-}
splitApAfter :: MonadCatch m splitApAfter :: MonadCatch m
=> Int -> SerialT m Int -> m Bool => Int -> SerialT m Int -> m ()
splitApAfter value = splitApAfter value =
IP.parse (PR.all (<= (value `div` 2)) <* PR.any (> value)) IP.parse
( PR.drainWhile (<= (value `div` 2))
<* PR.drainWhile (<= value)
)
{-# INLINE splitWith #-} {-# INLINE splitWith #-}
splitWith :: MonadCatch m splitWith :: MonadCatch m
=> Int -> SerialT m Int -> m (Bool, Bool) => Int -> SerialT m Int -> m ((), ())
splitWith value = splitWith value =
IP.parse (PR.splitWith (,) (PR.all (<= (value `div` 2))) (PR.any (> value))) IP.parse
(PR.splitWith (,)
(PR.drainWhile (<= (value `div` 2)))
(PR.drainWhile (<= value))
)
{-# INLINE split_ #-} {-# INLINE split_ #-}
split_ :: MonadCatch m split_ :: MonadCatch m
=> Int -> SerialT m Int -> m Bool => Int -> SerialT m Int -> m ()
split_ value = split_ value =
IP.parse (PR.split_ (PR.all (<= (value `div` 2))) (PR.any (> value))) IP.parse
(PR.split_
(PR.drainWhile (<= (value `div` 2)))
(PR.drainWhile (<= value))
)
{-# INLINE teeAllAny #-} {-# INLINE teeAllAny #-}
teeAllAny :: (MonadCatch m, Ord a) teeAllAny :: MonadCatch m
=> a -> SerialT m a -> m (Bool, Bool) => Int -> SerialT m Int -> m ((), ())
teeAllAny value = teeAllAny value =
IP.parse (PR.teeWith (,) (PR.all (<= value)) (PR.any (> value))) IP.parse
(PR.teeWith (,)
(PR.drainWhile (<= value))
(PR.drainWhile (<= value))
)
{-# INLINE teeFstAllAny #-} {-# INLINE teeFstAllAny #-}
teeFstAllAny :: (MonadCatch m, Ord a) teeFstAllAny :: MonadCatch m
=> a -> SerialT m a -> m (Bool, Bool) => Int -> SerialT m Int -> m ((), ())
teeFstAllAny value = teeFstAllAny value =
IP.parse (PR.teeWithFst (,) (PR.all (<= value)) (PR.any (> value))) IP.parse
(PR.teeWithFst (,)
(PR.drainWhile (<= value))
(PR.drainWhile (<= value))
)
{-# INLINE shortestAllAny #-} {-# INLINE shortestAllAny #-}
shortestAllAny :: (MonadCatch m, Ord a) shortestAllAny :: MonadCatch m
=> a -> SerialT m a -> m Bool => Int -> SerialT m Int -> m ()
shortestAllAny value = shortestAllAny value =
IP.parse (PR.shortest (PR.all (<= value)) (PR.any (> value))) IP.parse
(PR.shortest
(PR.drainWhile (<= value))
(PR.drainWhile (<= value))
)
{-# INLINE longestAllAny #-} {-# INLINE longestAllAny #-}
longestAllAny :: (MonadCatch m, Ord a) longestAllAny :: MonadCatch m
=> a -> SerialT m a -> m Bool => Int -> SerialT m Int -> m ()
longestAllAny value = longestAllAny value =
IP.parse (PR.longest (PR.all (<= value)) (PR.any (> value))) IP.parse
(PR.longest
(PR.drainWhile (<= value))
(PR.drainWhile (<= value))
)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Parsers in which -fspec-constr-recursive=16 is problematic -- Parsers in which -fspec-constr-recursive=16 is problematic
@ -169,7 +196,7 @@ longestAllAny value =
{-# INLINE lookAhead #-} {-# INLINE lookAhead #-}
lookAhead :: MonadCatch m => Int -> SerialT m Int -> m () lookAhead :: MonadCatch m => Int -> SerialT m Int -> m ()
lookAhead value = lookAhead value =
IP.parse (PR.lookAhead (PR.takeWhile (<= value) FL.drain) *> pure ()) IP.parse (PR.lookAhead (PR.takeWhile (<= value) FL.drain) $> ())
{-# INLINE sequenceA #-} {-# INLINE sequenceA #-}
sequenceA :: MonadCatch m => Int -> SerialT m Int -> m Int sequenceA :: MonadCatch m => Int -> SerialT m Int -> m Int
@ -208,7 +235,7 @@ parseMany :: MonadCatch m => SerialT m Int -> m ()
parseMany = parseMany =
S.drain S.drain
. S.map getSum . S.map getSum
. IP.parseMany (PR.take 2 FL.mconcat) . IP.parseMany (PR.fromFold $ FL.ltake 2 FL.mconcat)
. S.map Sum . S.map Sum
{-# INLINE parseIterate #-} {-# INLINE parseIterate #-}
@ -216,7 +243,7 @@ parseIterate :: MonadCatch m => SerialT m Int -> m ()
parseIterate = parseIterate =
S.drain S.drain
. S.map getSum . S.map getSum
. IP.parseIterate (\b -> (PR.take 2 (FL.sconcat b))) (Sum 0) . IP.parseIterate (PR.fromFold . FL.ltake 2 . FL.sconcat) (Sum 0)
. S.map Sum . S.map Sum
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -228,11 +255,9 @@ moduleName = "Data.Parser"
o_1_space_serial :: Int -> [Benchmark] o_1_space_serial :: Int -> [Benchmark]
o_1_space_serial value = o_1_space_serial value =
[ benchIOSink value "any" $ any value [ benchIOSink value "takeEQ" $ takeEQ value
, benchIOSink value "all" $ all value
, benchIOSink value "take" $ take value
, benchIOSink value "takeEQ" $ takeEQ value
, benchIOSink value "takeWhile" $ takeWhile value , benchIOSink value "takeWhile" $ takeWhile value
, benchIOSink value "drainWhile" $ drainWhile value
, benchIOSink value "splitAp" $ splitAp value , benchIOSink value "splitAp" $ splitAp value
, benchIOSink value "splitApBefore" $ splitApBefore value , benchIOSink value "splitApBefore" $ splitApBefore value
, benchIOSink value "splitApAfter" $ splitApAfter value , benchIOSink value "splitApAfter" $ splitApAfter value
@ -284,12 +309,6 @@ main = do
where where
allBenchmarks value = allBenchmarks value =
[ bgroup (o_1_space_prefix moduleName) $ concat [ bgroup (o_1_space_prefix moduleName) (o_1_space_serial value)
[ , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
o_1_space_serial value
]
, bgroup (o_n_heap_prefix moduleName) $ concat
[
o_n_heap_serial value
]
] ]

View File

@ -16,6 +16,7 @@ module Main
import Control.DeepSeq (NFData(..)) import Control.DeepSeq (NFData(..))
import Control.Monad.Catch (MonadCatch, MonadThrow) import Control.Monad.Catch (MonadCatch, MonadThrow)
import Data.Foldable (asum) import Data.Foldable (asum)
import Data.Functor (($>))
import System.Random (randomRIO) import System.Random (randomRIO)
import Prelude hiding (any, all, take, sequence, sequenceA, takeWhile) import Prelude hiding (any, all, take, sequence, sequenceA, takeWhile)
@ -58,21 +59,13 @@ benchIOSink value name f =
-- Parsers -- Parsers
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
{-# INLINE any #-} {-# INLINE drainWhile #-}
any :: (MonadThrow m, Ord a) => a -> SerialT m a -> m Bool drainWhile :: MonadThrow m => (a -> Bool) -> PR.Parser m a ()
any value = IP.parseD (PR.any (> value)) drainWhile p = PR.takeWhile p FL.drain
{-# INLINE all #-}
all :: (MonadThrow m, Ord a) => a -> SerialT m a -> m Bool
all value = IP.parseD (PR.all (<= value))
{-# INLINE take #-}
take :: MonadThrow m => Int -> SerialT m a -> m ()
take value = IP.parseD (PR.take value FL.drain)
{-# INLINE takeWhile #-} {-# INLINE takeWhile #-}
takeWhile :: MonadThrow m => Int -> SerialT m Int -> m () takeWhile :: MonadThrow m => Int -> SerialT m Int -> m ()
takeWhile value = IP.parseD (PR.takeWhile (<= value) FL.drain) takeWhile value = IP.parseD (drainWhile (<= value))
{-# INLINE many #-} {-# INLINE many #-}
many :: MonadCatch m => SerialT m Int -> m Int many :: MonadCatch m => SerialT m Int -> m Int
@ -103,33 +96,53 @@ manyTill value =
{-# INLINE splitAllAny #-} {-# INLINE splitAllAny #-}
splitAllAny :: MonadThrow m splitAllAny :: MonadThrow m
=> Int -> SerialT m Int -> m (Bool, Bool) => Int -> SerialT m Int -> m ((), ())
splitAllAny value = splitAllAny value =
IP.parseD ((,) <$> PR.all (<= (value `div` 2)) <*> PR.any (> value)) IP.parseD
((,)
<$> drainWhile (<= (value `div` 2))
<*> drainWhile (<= value)
)
{-# INLINE teeAllAny #-} {-# INLINE teeAllAny #-}
teeAllAny :: (MonadThrow m, Ord a) teeAllAny :: MonadThrow m
=> a -> SerialT m a -> m (Bool, Bool) => Int -> SerialT m Int -> m ((), ())
teeAllAny value = teeAllAny value =
IP.parseD (PR.teeWith (,) (PR.all (<= value)) (PR.any (> value))) IP.parseD
(PR.teeWith (,)
(drainWhile (<= value))
(drainWhile (<= value))
)
{-# INLINE teeFstAllAny #-} {-# INLINE teeFstAllAny #-}
teeFstAllAny :: (MonadThrow m, Ord a) teeFstAllAny :: MonadThrow m
=> a -> SerialT m a -> m (Bool, Bool) => Int -> SerialT m Int -> m ((), ())
teeFstAllAny value = teeFstAllAny value =
IP.parseD (PR.teeWithFst (,) (PR.all (<= value)) (PR.any (> value))) IP.parseD
(PR.teeWithFst (,)
(drainWhile (<= value))
(drainWhile (<= value))
)
{-# INLINE shortestAllAny #-} {-# INLINE shortestAllAny #-}
shortestAllAny :: (MonadThrow m, Ord a) shortestAllAny :: MonadThrow m
=> a -> SerialT m a -> m Bool => Int -> SerialT m Int -> m ()
shortestAllAny value = shortestAllAny value =
IP.parseD (PR.shortest (PR.all (<= value)) (PR.any (> value))) IP.parseD
(PR.shortest
(drainWhile (<= value))
(drainWhile (<= value))
)
{-# INLINE longestAllAny #-} {-# INLINE longestAllAny #-}
longestAllAny :: (MonadCatch m, Ord a) longestAllAny :: MonadCatch m
=> a -> SerialT m a -> m Bool => Int -> SerialT m Int -> m ()
longestAllAny value = longestAllAny value =
IP.parseD (PR.longest (PR.all (<= value)) (PR.any (> value))) IP.parseD
(PR.longest
(drainWhile (<= value))
(drainWhile (<= value))
)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Parsers in which -fspec-constr-recursive=16 is problematic -- Parsers in which -fspec-constr-recursive=16 is problematic
@ -142,7 +155,7 @@ longestAllAny value =
{-# INLINE lookAhead #-} {-# INLINE lookAhead #-}
lookAhead :: MonadThrow m => Int -> SerialT m Int -> m () lookAhead :: MonadThrow m => Int -> SerialT m Int -> m ()
lookAhead value = lookAhead value =
IP.parseD (PR.lookAhead (PR.takeWhile (<= value) FL.drain) *> pure ()) IP.parseD (PR.lookAhead (PR.takeWhile (<= value) FL.drain) $> ())
{-# INLINE sequenceA_ #-} {-# INLINE sequenceA_ #-}
sequenceA_ :: MonadThrow m => Int -> SerialT m Int -> m () sequenceA_ :: MonadThrow m => Int -> SerialT m Int -> m ()
@ -181,10 +194,7 @@ moduleName = "Data.Parser.ParserD"
o_1_space_serial :: Int -> [Benchmark] o_1_space_serial :: Int -> [Benchmark]
o_1_space_serial value = o_1_space_serial value =
[ benchIOSink value "any" $ any value [ benchIOSink value "takeWhile" $ takeWhile value
, benchIOSink value "all" $ all value
, benchIOSink value "take" $ take value
, benchIOSink value "takeWhile" $ takeWhile value
, benchIOSink value "split (all,any)" $ splitAllAny value , benchIOSink value "split (all,any)" $ splitAllAny value
, benchIOSink value "many" many , benchIOSink value "many" many
, benchIOSink value "some" some , benchIOSink value "some" some
@ -228,16 +238,7 @@ main = do
where where
allBenchmarks value = allBenchmarks value =
[ bgroup (o_1_space_prefix moduleName) $ concat [ bgroup (o_1_space_prefix moduleName) (o_1_space_serial value)
[ , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
o_1_space_serial value , bgroup (o_n_space_prefix moduleName) (o_n_space_serial value)
]
, bgroup (o_n_heap_prefix moduleName) $ concat
[
o_n_heap_serial value
]
, bgroup (o_n_space_prefix moduleName) $ concat
[
o_n_space_serial value
]
] ]

View File

@ -69,30 +69,6 @@ benchIOSink value name f =
satisfy :: MonadCatch m => (a -> Bool) -> PR.Parser m a a satisfy :: MonadCatch m => (a -> Bool) -> PR.Parser m a a
satisfy = PR.toParserK . PRD.satisfy satisfy = PR.toParserK . PRD.satisfy
{-# INLINE any #-}
any :: MonadCatch m => (a -> Bool) -> PR.Parser m a Bool
any = PR.toParserK . PRD.any
{-# INLINE anyK #-}
anyK :: (MonadCatch m, Ord a) => a -> SerialT m a -> m Bool
anyK value = PARSE_OP (any (> value))
{-# INLINE all #-}
all :: MonadCatch m => (a -> Bool) -> PR.Parser m a Bool
all = PR.toParserK . PRD.all
{-# INLINE allK #-}
allK :: (MonadCatch m, Ord a) => a -> SerialT m a -> m Bool
allK value = PARSE_OP (all (<= value))
{-# INLINE take #-}
take :: MonadCatch m => Int -> PR.Parser m a ()
take value = PR.toParserK $ PRD.take value FL.drain
{-# INLINE takeK #-}
takeK :: MonadCatch m => Int -> SerialT m a -> m ()
takeK value = PARSE_OP (take value)
{-# INLINE takeWhile #-} {-# INLINE takeWhile #-}
takeWhile :: MonadCatch m => (a -> Bool) -> PR.Parser m a () takeWhile :: MonadCatch m => (a -> Bool) -> PR.Parser m a ()
takeWhile p = PR.toParserK $ PRD.takeWhile p FL.drain takeWhile p = PR.toParserK $ PRD.takeWhile p FL.drain
@ -103,9 +79,9 @@ takeWhileK value = PARSE_OP (takeWhile (<= value))
{-# INLINE splitApp #-} {-# INLINE splitApp #-}
splitApp :: MonadCatch m splitApp :: MonadCatch m
=> Int -> SerialT m Int -> m (Bool, Bool) => Int -> SerialT m Int -> m ((), ())
splitApp value = splitApp value =
PARSE_OP ((,) <$> any (>= (value `div` 2)) <*> any (> value)) PARSE_OP ((,) <$> takeWhile (<= (value `div` 2)) <*> takeWhile (<= value))
{-# INLINE sequenceA #-} {-# INLINE sequenceA #-}
sequenceA :: MonadCatch m => Int -> SerialT m Int -> m Int sequenceA :: MonadCatch m => Int -> SerialT m Int -> m Int
@ -157,10 +133,7 @@ moduleName = "Data.Parser.ParserK"
o_1_space_serial :: Int -> [Benchmark] o_1_space_serial :: Int -> [Benchmark]
o_1_space_serial value = o_1_space_serial value =
[ benchIOSink value "any" $ anyK value [ benchIOSink value "takeWhile" $ takeWhileK value
, benchIOSink value "all" $ allK value
, benchIOSink value "take" $ takeK value
, benchIOSink value "takeWhile" $ takeWhileK value
, benchIOSink value "splitApp" $ splitApp value , benchIOSink value "splitApp" $ splitApp value
] ]
@ -187,10 +160,6 @@ main = do
where where
allBenchmarks value = allBenchmarks value =
[ bgroup (o_1_space_prefix moduleName) $ concat [ bgroup (o_1_space_prefix moduleName) (o_1_space_serial value)
[ o_1_space_serial value , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
]
, bgroup (o_n_heap_prefix moduleName) $ concat
[ o_n_heap_serial value
]
] ]

View File

@ -54,8 +54,6 @@ module Streamly.Internal.Data.Parser
-- First order parsers -- First order parsers
-- * Accumulators -- * Accumulators
, fromFold , fromFold
, any
, all
, yield , yield
, yieldM , yieldM
, die , die
@ -75,8 +73,7 @@ module Streamly.Internal.Data.Parser
-- | Grab a sequence of input elements without inspecting them -- | Grab a sequence of input elements without inspecting them
, takeBetween , takeBetween
, take -- takeBetween 0 n -- , take -- takeBetween 0 n
-- $take
, takeEQ -- takeBetween n n , takeEQ -- takeBetween n n
, takeGE -- takeBetween n maxBound , takeGE -- takeBetween n maxBound
@ -86,11 +83,9 @@ module Streamly.Internal.Data.Parser
, takeWhile , takeWhile
-- $takeWhile -- $takeWhile
, takeWhile1 , takeWhile1
, drainWhile
, sliceSepByP
, sliceSepBy , sliceSepBy
, sliceSepByMax
, sliceEndWith
, sliceBeginWith , sliceBeginWith
, sliceSepWith , sliceSepWith
, escapedSliceSepBy , escapedSliceSepBy
@ -134,7 +129,7 @@ module Streamly.Internal.Data.Parser
-- * N-ary Combinators -- * N-ary Combinators
-- ** Sequential Collection -- ** Sequential Collection
, sequence , concatSequence
, concatMap , concatMap
-- ** Sequential Repetition -- ** Sequential Repetition
@ -206,6 +201,7 @@ import Prelude
import Streamly.Internal.Data.Fold.Types (Fold(..)) import Streamly.Internal.Data.Fold.Types (Fold(..))
import Streamly.Internal.Data.Parser.ParserK.Types (Parser) import Streamly.Internal.Data.Parser.ParserK.Types (Parser)
import qualified Streamly.Internal.Data.Fold as FL
import qualified Streamly.Internal.Data.Parser.ParserD as D import qualified Streamly.Internal.Data.Parser.ParserD as D
import qualified Streamly.Internal.Data.Parser.ParserK.Types as K import qualified Streamly.Internal.Data.Parser.ParserK.Types as K
@ -225,22 +221,6 @@ fromFold = K.toParserK . D.fromFold
-- Terminating but not failing folds -- Terminating but not failing folds
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- --
-- |
-- >>> S.parse (PR.any (== 0)) $ S.fromList [1,0,1]
-- > True
--
{-# INLINE any #-}
any :: MonadCatch m => (a -> Bool) -> Parser m a Bool
any = K.toParserK . D.any
-- |
-- >>> S.parse (PR.all (== 0)) $ S.fromList [1,0,1]
-- > False
--
{-# INLINE all #-}
all :: MonadCatch m => (a -> Bool) -> Parser m a Bool
all = K.toParserK . D.all
-- This is the dual of stream "yield". -- This is the dual of stream "yield".
-- --
-- | A parser that always yields a pure value without consuming any input. -- | A parser that always yields a pure value without consuming any input.
@ -377,35 +357,6 @@ takeBetween :: -- MonadCatch m =>
Int -> Int -> Fold m a b -> Parser m a b Int -> Int -> Fold m a b -> Parser m a b
takeBetween _m _n = undefined -- K.toParserK . D.takeBetween m n takeBetween _m _n = undefined -- K.toParserK . D.takeBetween m n
--
-- $take
-- Note: this is called takeP in some parser libraries.
--
-- TODO Once we have terminating folds, this Parse should get replaced by Fold.
-- Alternatively, we can name it "chunkOf" and the corresponding time domain
-- combinator as "intervalOf" or even "chunk" and "interval".
-- | Take at most @n@ input elements and fold them using the supplied fold.
--
-- Stops after @n@ elements.
-- Never fails.
--
-- >>> S.parse (PR.take 1 FL.toList) $ S.fromList [1]
-- [1]
--
-- >>> S.parse (PR.take (-1) FL.toList) $ S.fromList [1]
-- []
--
-- @
-- S.chunksOf n f = S.parseMany (FL.take n f)
-- @
--
-- /Internal/
--
{-# INLINE take #-}
take :: MonadCatch m => Int -> Fold m a b -> Parser m a b
take n = K.toParserK . D.take n
-- | Stops after taking exactly @n@ input elements. -- | Stops after taking exactly @n@ input elements.
-- --
-- * Stops - after consuming @n@ elements. -- * Stops - after consuming @n@ elements.
@ -423,8 +374,9 @@ takeEQ n = K.toParserK . D.takeEQ n
-- | Take at least @n@ input elements, but can collect more. -- | Take at least @n@ input elements, but can collect more.
-- --
-- * Stops - never. -- * Stops - when the collecting fold stops.
-- * Fails - if the stream end before producing @n@ elements. -- * Fails - if the stream or the collecting fold ends before producing @n@
-- elements.
-- --
-- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1] -- >>> S.parse (PR.takeGE 4 FL.toList) $ S.fromList [1,0,1]
-- > "takeGE: Expecting at least 4 elements, got only 3" -- > "takeGE: Expecting at least 4 elements, got only 3"
@ -465,7 +417,7 @@ takeWhileP _cond = undefined -- K.toParserK . D.takeWhileP cond
-- | Collect stream elements until an element fails the predicate. The element -- | Collect stream elements until an element fails the predicate. The element
-- on which the predicate fails is returned back to the input stream. -- on which the predicate fails is returned back to the input stream.
-- --
-- * Stops - when the predicate fails. -- * Stops - when the predicate fails or the collecting fold stops.
-- * Fails - never. -- * Fails - never.
-- --
-- >>> S.parse (PR.takeWhile (== 0) FL.toList) $ S.fromList [0,0,1,0,1] -- >>> S.parse (PR.takeWhile (== 0) FL.toList) $ S.fromList [0,0,1,0,1]
@ -491,9 +443,19 @@ takeWhile cond = K.toParserK . D.takeWhile cond
takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b takeWhile1 :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b
takeWhile1 cond = K.toParserK . D.takeWhile1 cond takeWhile1 cond = K.toParserK . D.takeWhile1 cond
-- | Like 'sliceSepBy' but uses a 'Parser' instead of a 'Fold' to collect the -- | Drain the input as long as the predicate succeeds, running the effects and
-- input. @sliceSepByP cond parser@ parses a slice of the input using @parser@ -- discarding the results.
-- until @cond@ succeeds or the parser stops. --
-- This is also called @skipWhile@ in some parsing libraries.
--
-- /Internal/
--
{-# INLINE drainWhile #-}
drainWhile :: MonadCatch m => (a -> Bool) -> Parser m a ()
drainWhile p = takeWhile p FL.drain
-- | @sliceSepBy cond parser@ parses a slice of the input using @parser@ until
-- @cond@ succeeds or the parser stops.
-- --
-- This is a generalized slicing parser which can be used to implement other -- This is a generalized slicing parser which can be used to implement other
-- parsers e.g.: -- parsers e.g.:
@ -505,59 +467,10 @@ takeWhile1 cond = K.toParserK . D.takeWhile1 cond
-- --
-- /Unimplemented/ -- /Unimplemented/
-- --
{-# INLINABLE sliceSepByP #-}
sliceSepByP :: -- MonadCatch m =>
(a -> Bool) -> Parser m a b -> Parser m a b
sliceSepByP _cond = undefined -- K.toParserK . D.sliceSepByP cond
-- Note: Keep this consistent with S.splitOn. In fact we should eliminate
-- S.splitOn in favor of the parser.
--
-- | Split on an infixed separator element, dropping the separator. Splits the
-- stream on separator elements determined by the supplied predicate, separator
-- is considered as infixed between two segments, if one side of the separator
-- is missing then it is parsed as an empty stream. The supplied 'Fold' is
-- applied on the split segments. With '-' representing non-separator elements
-- and '.' as separator, 'splitOn' splits as follows:
--
-- @
-- "--.--" => "--" "--"
-- "--." => "--" ""
-- ".--" => "" "--"
-- @
--
-- @PR.sliceSepBy (== x)@ is an inverse of @S.intercalate (S.yield x)@
--
-- Let's use the following definition for illustration:
--
-- > splitOn p = PR.many FL.toList $ PR.sliceSepBy p (FL.toList)
-- > splitOn' p = S.parse (splitOn p) . S.fromList
--
-- >>> splitOn' (== '.') ""
-- [""]
--
-- >>> splitOn' (== '.') "."
-- ["",""]
--
-- >>> splitOn' (== '.') ".a"
-- > ["","a"]
--
-- >>> splitOn' (== '.') "a."
-- > ["a",""]
--
-- >>> splitOn' (== '.') "a.b"
-- > ["a","b"]
--
-- >>> splitOn' (== '.') "a..b"
-- > ["a","","b"]
--
-- * Stops - when the predicate succeeds.
-- * Fails - never.
--
-- /Internal/
{-# INLINABLE sliceSepBy #-} {-# INLINABLE sliceSepBy #-}
sliceSepBy :: MonadCatch m => (a -> Bool) -> Fold m a b -> Parser m a b sliceSepBy :: -- MonadCatch m =>
sliceSepBy cond = K.toParserK . D.sliceSepBy cond (a -> Bool) -> Parser m a b -> Parser m a b
sliceSepBy _cond = undefined -- K.toParserK . D.sliceSepBy cond
-- | Like 'sliceSepBy' but does not drop the separator element, instead -- | Like 'sliceSepBy' but does not drop the separator element, instead
-- separator is emitted as a separate element in the output. -- separator is emitted as a separate element in the output.
@ -568,23 +481,6 @@ sliceSepWith :: -- MonadCatch m =>
(a -> Bool) -> Fold m a b -> Parser m a b (a -> Bool) -> Fold m a b -> Parser m a b
sliceSepWith _cond = undefined -- K.toParserK . D.sliceSepBy cond sliceSepWith _cond = undefined -- K.toParserK . D.sliceSepBy cond
-- | Collect stream elements until an element succeeds the predicate. Also take
-- the element on which the predicate succeeded. The succeeding element is
-- treated as a suffix separator which is kept in the output segement.
--
-- * Stops - when the predicate succeeds.
-- * Fails - never.
--
-- S.splitWithSuffix pred f = S.parseMany (PR.sliceEndWith pred f)
--
-- /Unimplemented/
--
{-# INLINABLE sliceEndWith #-}
sliceEndWith ::
-- Monad m =>
(a -> Bool) -> Fold m a b -> Parser m a b
sliceEndWith = undefined
-- | Collect stream elements until an elements passes the predicate, return the -- | Collect stream elements until an elements passes the predicate, return the
-- last element on which the predicate succeeded back to the input stream. If -- last element on which the predicate succeeded back to the input stream. If
-- the predicate succeeds on the first element itself then it is kept in the -- the predicate succeeds on the first element itself then it is kept in the
@ -604,44 +500,6 @@ sliceBeginWith ::
(a -> Bool) -> Fold m a b -> Parser m a b (a -> Bool) -> Fold m a b -> Parser m a b
sliceBeginWith = undefined sliceBeginWith = undefined
-- | Like 'sliceSepBy' but terminates a parse even before the separator
-- is encountered if its size exceeds the specified maximum limit.
--
-- > take n = PR.sliceSepByMax (const True) n
-- > sliceSepBy p = PR.sliceSepByMax p maxBound
--
-- Let's use the following definitions for illustration:
--
-- > splitOn p n = PR.many FL.toList $ PR.sliceSepByMax p n (FL.toList)
-- > splitOn' p n = S.parse (splitOn p n) . S.fromList
--
-- >>> splitOn' (== '.') 0 ""
-- [""]
--
-- >>> splitOn' (== '.') 0 "a"
-- infinite list of empty strings
--
-- >>> splitOn' (== '.') 3 "hello.world"
-- ["hel","lo","wor","ld"]
--
-- If the separator is found and the limit is reached at the same time then it
-- behaves just like 'sliceSepBy' i.e. the separator is dropped.
--
-- >>> splitOn' (== '.') 0 "."
-- ["",""]
--
-- >>> splitOn' (== '.') 0 ".."
-- ["","",""]
--
-- * Stops - when the predicate succeeds or the limit is reached.
-- * Fails - never.
--
-- /Internal/
{-# INLINABLE sliceSepByMax #-}
sliceSepByMax :: MonadCatch m
=> (a -> Bool) -> Int -> Fold m a b -> Parser m a b
sliceSepByMax cond cnt = K.toParserK . D.sliceSepByMax cond cnt
-- | Like 'sliceSepBy' but the separator elements can be escaped using an -- | Like 'sliceSepBy' but the separator elements can be escaped using an
-- escape char determined by the second predicate. -- escape char determined by the second predicate.
-- --
@ -911,18 +769,19 @@ deintercalate = undefined
-- Sequential Collection -- Sequential Collection
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- --
-- | @sequence f t@ collects sequential parses of parsers in the container @t@ -- | @concatSequence f t@ collects sequential parses of parsers in the
-- using the fold @f@. Fails if the input ends or any of the parsers fail. -- container @t@ using the fold @f@. Fails if the input ends or any of the
-- parsers fail.
-- --
-- This is same as 'Data.Traversable.sequence' but more efficient. -- This is same as 'Data.Traversable.sequence' but more efficient.
-- --
-- /Unimplemented/ -- /Unimplemented/
-- --
{-# INLINE sequence #-} {-# INLINE concatSequence #-}
sequence :: concatSequence ::
-- Foldable t => -- Foldable t =>
Fold m b c -> t (Parser m a b) -> Parser m a c Fold m b c -> t (Parser m a b) -> Parser m a c
sequence _f _p = undefined concatSequence _f _p = undefined
-- | Map a 'Parser' returning function on the result of a 'Parser'. -- | Map a 'Parser' returning function on the result of a 'Parser'.
-- --
@ -974,10 +833,11 @@ manyP :: -- MonadCatch m =>
Parser m b c -> Parser m a b -> Parser m a c Parser m b c -> Parser m a b -> Parser m a c
manyP _f _p = undefined -- K.toParserK $ D.manyP f (K.fromParserK p) manyP _f _p = undefined -- K.toParserK $ D.manyP f (K.fromParserK p)
-- | Collect zero or more parses. Apply the parser repeatedly on the input -- | Collect zero or more parses. Apply the supplied parser repeatedly on the
-- stream, stop when the parser fails, accumulate zero or more parse results -- input stream and push the parse results to a downstream fold.
-- using the supplied 'Fold'. This parser never fails, in case the first --
-- application of parser fails it returns an empty result. -- Stops: when the downstream fold stops or the parser fails.
-- Fails: never, produces zero or more results.
-- --
-- Compare with 'Control.Applicative.many'. -- Compare with 'Control.Applicative.many'.
-- --
@ -988,10 +848,15 @@ many :: MonadCatch m => Fold m b c -> Parser m a b -> Parser m a c
many f p = K.toParserK $ D.many f (K.fromParserK p) many f p = K.toParserK $ D.many f (K.fromParserK p)
-- many = countBetween 0 maxBound -- many = countBetween 0 maxBound
-- Note: many1 would perhaps be a better name for this and consistent with
-- other names like takeWhile1. But we retain the name "some" for
-- compatibility.
--
-- | Collect one or more parses. Apply the supplied parser repeatedly on the -- | Collect one or more parses. Apply the supplied parser repeatedly on the
-- input stream and accumulate the parse results as long as the parser -- input stream and push the parse results to a downstream fold.
-- succeeds, stop when it fails. This parser fails if not even one result is --
-- collected. -- Stops: when the downstream fold stops or the parser fails.
-- Fails: if it stops without producing a single result.
-- --
-- @some fld parser = many (takeGE 1 fld) parser@ -- @some fld parser = many (takeGE 1 fld) parser@
-- --
@ -1054,6 +919,8 @@ manyTillP _f _p1 _p2 = undefined
-- @test@ is discarded and the output of @collect@ is accumulated by the -- @test@ is discarded and the output of @collect@ is accumulated by the
-- supplied fold. The parser fails if @collect@ fails. -- supplied fold. The parser fails if @collect@ fails.
-- --
-- Stops when the fold @f@ stops.
--
-- /Internal/ -- /Internal/
-- --
{-# INLINE manyTill #-} {-# INLINE manyTill #-}

View File

@ -19,8 +19,6 @@ module Streamly.Internal.Data.Parser.ParserD
-- First order parsers -- First order parsers
-- * Accumulators -- * Accumulators
, fromFold , fromFold
, any
, all
, yield , yield
, yieldM , yieldM
, die , die
@ -45,7 +43,6 @@ module Streamly.Internal.Data.Parser.ParserD
-- takeWhileBetween cond m n p = takeWhile cond (takeBetween m n p) -- takeWhileBetween cond m n p = takeWhile cond (takeBetween m n p)
-- --
-- Grab a sequence of input elements without inspecting them -- Grab a sequence of input elements without inspecting them
, take
-- , takeBetween -- , takeBetween
-- , takeLE -- take -- takeBetween 0 n -- , takeLE -- take -- takeBetween 0 n
-- , takeLE1 -- take1 -- takeBetween 1 n -- , takeLE1 -- take1 -- takeBetween 1 n
@ -57,9 +54,7 @@ module Streamly.Internal.Data.Parser.ParserD
, takeWhile , takeWhile
, takeWhile1 , takeWhile1
, sliceSepBy , sliceSepBy
, sliceSepByMax
-- , sliceSepByBetween -- , sliceSepByBetween
, sliceEndWith
, sliceBeginWith , sliceBeginWith
-- , sliceSepWith -- , sliceSepWith
-- --
@ -164,7 +159,6 @@ import Streamly.Internal.Data.Fold.Types (Fold(..))
import Streamly.Internal.Data.Tuple.Strict (Tuple'(..)) import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
import qualified Streamly.Internal.Data.Fold.Types as FL import qualified Streamly.Internal.Data.Fold.Types as FL
import qualified Streamly.Internal.Data.Fold as FL
import Prelude hiding import Prelude hiding
(any, all, take, takeWhile, sequence, concatMap, maybe, either) (any, all, take, takeWhile, sequence, concatMap, maybe, either)
@ -192,19 +186,6 @@ fromFold (Fold fstep finitial fextract) = Parser step finitial fextract
FL.Partial s1 -> Partial 0 s1 FL.Partial s1 -> Partial 0 s1
FL.Done b -> Done 0 b FL.Done b -> Done 0 b
-------------------------------------------------------------------------------
-- Terminating but not failing folds
-------------------------------------------------------------------------------
--
{-# INLINE any #-}
any :: Monad m => (a -> Bool) -> Parser m a Bool
any predicate = fromFold $ FL.any predicate
{-# INLINABLE all #-}
all :: Monad m => (a -> Bool) -> Parser m a Bool
all predicate = fromFold $ FL.all predicate
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Failing Parsers -- Failing Parsers
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -300,16 +281,6 @@ either parser = Parser step initial extract
-- Taking elements -- Taking elements
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- It will be inconsistent with other takeish combinators.
-- This is takeLE
-- | See 'Streamly.Internal.Data.Parser.take'.
--
-- /Internal/
--
{-# INLINE take #-}
take :: Monad m => Int -> Fold m a b -> Parser m a b
take n fld = fromFold $ FL.ltake n fld
-- | See 'Streamly.Internal.Data.Parser.takeEQ'. -- | See 'Streamly.Internal.Data.Parser.takeEQ'.
-- --
-- /Internal/ -- /Internal/
@ -340,6 +311,7 @@ takeEQ cnt (Fold fstep finitial fextract) = Parser step initial extract
<$> case res of <$> case res of
FL.Partial s -> fextract s FL.Partial s -> fextract s
FL.Done b -> return b FL.Done b -> return b
-- XXX we should not reach here when initial returns Step type
-- reachable only when n == 0 -- reachable only when n == 0
| otherwise = Done 1 <$> fextract r | otherwise = Done 1 <$> fextract r
@ -420,7 +392,6 @@ takeWhile predicate (Fold fstep finitial fextract) =
FL.Done b -> Done 0 b FL.Done b -> Done 0 b
else Done 1 <$> fextract s else Done 1 <$> fextract s
-- | See 'Streamly.Internal.Data.Parser.takeWhile1'. -- | See 'Streamly.Internal.Data.Parser.takeWhile1'.
-- --
-- /Internal/ -- /Internal/
@ -443,7 +414,7 @@ takeWhile1 predicate (Fold fstep finitial fextract) =
$ case sr of $ case sr of
FL.Partial r -> Partial 0 (Just r) FL.Partial r -> Partial 0 (Just r)
FL.Done b -> Done 0 b FL.Done b -> Done 0 b
else return $ Error err else return $ Error "takeWhile1: predicate failed on first element"
step (Just s) a = step (Just s) a =
if predicate a if predicate a
then do then do
@ -455,28 +426,16 @@ takeWhile1 predicate (Fold fstep finitial fextract) =
b <- fextract s b <- fextract s
return $ Done 1 b return $ Done 1 b
extract Nothing = throwM $ ParseError err extract Nothing = throwM $ ParseError "takeWhile1: end of input"
extract (Just s) = fextract s extract (Just s) = fextract s
err = "takeWhile1: end of input"
-- | See 'Streamly.Internal.Data.Parser.sliceSepBy'. -- | See 'Streamly.Internal.Data.Parser.sliceSepBy'.
-- --
-- /Internal/ -- /Internal/
-- --
{-# INLINABLE sliceSepBy #-} sliceSepBy :: -- MonadCatch m =>
sliceSepBy :: Monad m => (a -> Bool) -> Fold m a b -> Parser m a b (a -> Bool) -> Parser m a b -> Parser m a b
sliceSepBy predicate fld = fromFold $ FL.sliceSepBy predicate fld sliceSepBy _cond = undefined
-- | See 'Streamly.Internal.Data.Parser.sliceEndWith'.
--
-- /Unimplemented/
--
{-# INLINABLE sliceEndWith #-}
sliceEndWith ::
-- Monad m =>
(a -> Bool) -> Fold m a b -> Parser m a b
sliceEndWith = undefined
-- | See 'Streamly.Internal.Data.Parser.sliceBeginWith'. -- | See 'Streamly.Internal.Data.Parser.sliceBeginWith'.
-- --
@ -488,15 +447,6 @@ sliceBeginWith ::
(a -> Bool) -> Fold m a b -> Parser m a b (a -> Bool) -> Fold m a b -> Parser m a b
sliceBeginWith = undefined sliceBeginWith = undefined
-- | See 'Streamly.Internal.Data.Parser.sliceSepByMax'.
--
-- /Internal/
--
{-# INLINABLE sliceSepByMax #-}
sliceSepByMax :: Monad m
=> (a -> Bool) -> Int -> Fold m a b -> Parser m a b
sliceSepByMax p n = sliceSepBy p . FL.ltake n
-- | See 'Streamly.Internal.Data.Parser.wordBy'. -- | See 'Streamly.Internal.Data.Parser.wordBy'.
-- --
-- /Unimplemented/ -- /Unimplemented/
@ -709,6 +659,7 @@ manyTill (Fold fstep finitial fextract)
Error _ -> do Error _ -> do
rR <- initialL rR <- initialL
return $ Continue (cnt + 1) (ManyTillL 0 fs rR) return $ Continue (cnt + 1) (ManyTillL 0 fs rR)
-- XXX the cnt is being used only by the assert
step (ManyTillL cnt fs st) a = do step (ManyTillL cnt fs st) a = do
r <- stepL st a r <- stepL st a
case r of case r of
@ -717,17 +668,17 @@ manyTill (Fold fstep finitial fextract)
assert (cnt + 1 - n >= 0) (return ()) assert (cnt + 1 - n >= 0) (return ())
return $ Continue n (ManyTillL (cnt + 1 - n) fs s) return $ Continue n (ManyTillL (cnt + 1 - n) fs s)
Done n b -> do Done n b -> do
sfs1 <- fstep fs b fs1 <- fstep fs b
case sfs1 of case fs1 of
FL.Partial fs1 -> do FL.Partial s -> do
l <- initialR l <- initialR
return $ Partial n (ManyTillR 0 fs1 l) return $ Partial n (ManyTillR 0 s l)
FL.Done fb -> return $ Done n fb FL.Done b1 -> return $ Done n b1
Error err -> return $ Error err Error err -> return $ Error err
extract (ManyTillL _ fs sR) = do extract (ManyTillL _ fs sR) = do
res <- extractL sR >>= fstep fs res <- extractL sR >>= fstep fs
case res of case res of
FL.Partial sres -> fextract sres FL.Partial s -> fextract s
FL.Done bres -> return bres FL.Done b -> return b
extract (ManyTillR _ fs _) = fextract fs extract (ManyTillR _ fs _) = fextract fs

View File

@ -122,8 +122,8 @@ module Streamly.Internal.Data.Parser.ParserD.Types
, die , die
, dieM , dieM
, splitSome , splitSome -- parseSome?
, splitMany , splitMany -- parseMany?
, alt , alt
, concatMap , concatMap
) )
@ -274,6 +274,8 @@ yieldM b = Parser (\_ _ -> Done 1 <$> b) -- step
{-# ANN type SeqParseState Fuse #-} {-# ANN type SeqParseState Fuse #-}
data SeqParseState sl f sr = SeqParseL sl | SeqParseR f sr data SeqParseState sl f sr = SeqParseL sl | SeqParseR f sr
-- | See 'Streamly.Internal.Data.Parser.splitWith'.
--
-- Note: this implementation of splitWith is fast because of stream fusion but -- Note: this implementation of splitWith is fast because of stream fusion but
-- has quadratic time complexity, because each composition adds a new branch -- has quadratic time complexity, because each composition adds a new branch
-- that each subsequent parse's input element has to go through, therefore, it -- that each subsequent parse's input element has to go through, therefore, it
@ -281,8 +283,6 @@ data SeqParseState sl f sr = SeqParseL sl | SeqParseR f sr
-- compositions the performance starts dipping rapidly beyond a CPS style -- compositions the performance starts dipping rapidly beyond a CPS style
-- unfused implementation. -- unfused implementation.
-- --
-- | See 'Streamly.Internal.Data.Parser.splitWith'.
--
-- /Internal/ -- /Internal/
-- --
{-# INLINE splitWith #-} {-# INLINE splitWith #-}
@ -430,7 +430,6 @@ alt (Parser stepL initialL extractL) (Parser stepR initialR extractR) =
extract (AltParseR sR) = extractR sR extract (AltParseR sR) = extractR sR
extract (AltParseL _ sL) = extractL sL extract (AltParseL _ sL) = extractL sL
-- XXX We are ignoring the Error?
-- | See documentation of 'Streamly.Internal.Data.Parser.many'. -- | See documentation of 'Streamly.Internal.Data.Parser.many'.
-- --
-- /Internal/ -- /Internal/
@ -453,17 +452,14 @@ splitMany (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
let cnt1 = cnt + 1 let cnt1 = cnt + 1
case r of case r of
Partial n s -> do Partial n s -> do
-- XXX Combine assert with the next statement
assert (cnt1 - n >= 0) (return ()) assert (cnt1 - n >= 0) (return ())
return $ Continue n (Tuple3' s (cnt1 - n) fs) return $ Continue n (Tuple3' s (cnt1 - n) fs)
Continue n s -> do Continue n s -> do
-- XXX Combine assert with the next statement
assert (cnt1 - n >= 0) (return ()) assert (cnt1 - n >= 0) (return ())
return $ Continue n (Tuple3' s (cnt1 - n) fs) return $ Continue n (Tuple3' s (cnt1 - n) fs)
Done n b -> do Done n b -> do
s <- initial1 s <- initial1
fs1 <- fstep fs b fs1 <- fstep fs b
-- XXX Combine assert with the next statement
assert (cnt1 - n >= 0) (return ()) assert (cnt1 - n >= 0) (return ())
return return
$ case fs1 of $ case fs1 of
@ -484,8 +480,6 @@ splitMany (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
FL.Partial s1 -> fextract s1 FL.Partial s1 -> fextract s1
FL.Done b1 -> return b1 FL.Done b1 -> return b1
-- XXX Unwrap Either into their own constructors?
-- XXX I think haskell automatically does this though. Need to check.
-- | See documentation of 'Streamly.Internal.Data.Parser.some'. -- | See documentation of 'Streamly.Internal.Data.Parser.some'.
-- --
-- /Internal/ -- /Internal/
@ -505,6 +499,7 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
{-# INLINE step #-} {-# INLINE step #-}
step (Tuple3' st cnt (Left fs)) a = do step (Tuple3' st cnt (Left fs)) a = do
r <- step1 st a r <- step1 st a
-- In the Left state, count is used only for the assert
let cnt1 = cnt + 1 let cnt1 = cnt + 1
case r of case r of
Partial n s -> do Partial n s -> do
@ -514,6 +509,7 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
assert (cnt1 - n >= 0) (return ()) assert (cnt1 - n >= 0) (return ())
return $ Continue n (Tuple3' s (cnt1 - n) (Left fs)) return $ Continue n (Tuple3' s (cnt1 - n) (Left fs))
Done n b -> do Done n b -> do
assert (cnt1 - n >= 0) (return ())
s <- initial1 s <- initial1
fs1 <- fstep fs b fs1 <- fstep fs b
return return
@ -532,9 +528,9 @@ splitSome (Fold fstep finitial fextract) (Parser step1 initial1 extract1) =
assert (cnt1 - n >= 0) (return ()) assert (cnt1 - n >= 0) (return ())
return $ Continue n (Tuple3' s (cnt1 - n) (Right fs)) return $ Continue n (Tuple3' s (cnt1 - n) (Right fs))
Done n b -> do Done n b -> do
assert (cnt1 - n >= 0) (return ())
s <- initial1 s <- initial1
fs1 <- fstep fs b fs1 <- fstep fs b
assert (cnt1 - n >= 0) (return ())
return return
$ case fs1 of $ case fs1 of
FL.Partial s1 -> Partial n (Tuple3' s 0 (Right s1)) FL.Partial s1 -> Partial n (Tuple3' s 0 (Right s1))

View File

@ -783,7 +783,9 @@ readOneEvent cfg wt@(Watch _ wdMap) = do
-- XXX sliceSepByMax drops the separator so assumes a null -- XXX sliceSepByMax drops the separator so assumes a null
-- terminated path, we should use a takeWhile nested inside a -- terminated path, we should use a takeWhile nested inside a
-- takeP -- takeP
pth <- PR.sliceSepByMax (== 0) pathLen (A.writeN pathLen) pth <-
PR.fromFold
$ FL.sliceSepByMax (== 0) pathLen (A.writeN pathLen)
let remaining = pathLen - A.length pth - 1 let remaining = pathLen - A.length pth - 1
when (remaining /= 0) $ PR.takeEQ remaining FL.drain when (remaining /= 0) $ PR.takeEQ remaining FL.drain
return pth return pth

View File

@ -694,11 +694,13 @@ test-suite Data.Parser
ghc-options: -O2 ghc-options: -O2
type: exitcode-stdio-1.0 type: exitcode-stdio-1.0
main-is: Streamly/Test/Data/Parser.hs main-is: Streamly/Test/Data/Parser.hs
other-modules: Streamly.Test.Common
test-suite Data.Parser.ParserD test-suite Data.Parser.ParserD
import: test-options import: test-options
type: exitcode-stdio-1.0 type: exitcode-stdio-1.0
main-is: Streamly/Test/Data/Parser/ParserD.hs main-is: Streamly/Test/Data/Parser/ParserD.hs
other-modules: Streamly.Test.Common
test-suite Data.Array test-suite Data.Array
import: test-options import: test-options

View File

@ -1,16 +1,14 @@
module Main (main) where module Main (main) where
import Control.Exception (SomeException(..), displayException) import Control.Exception (SomeException(..), displayException)
import Control.Monad (when)
import Control.Monad.IO.Class (MonadIO(..))
import Data.List ((\\))
import Data.Word (Word8, Word32, Word64) import Data.Word (Word8, Word32, Word64)
import Streamly.Test.Common (listEquals, checkListEqual, chooseInt)
import Test.Hspec (Spec, hspec, describe) import Test.Hspec (Spec, hspec, describe)
import Test.Hspec.QuickCheck import Test.Hspec.QuickCheck
import Test.QuickCheck import Test.QuickCheck
(arbitrary, forAll, choose, elements, Property, property, listOf, (arbitrary, forAll, elements, Property, property, listOf,
vectorOf, counterexample, Gen, suchThat) vectorOf, Gen, suchThat)
import Test.QuickCheck.Monadic (monadicIO, PropertyM, assert, monitor, run) import Test.QuickCheck.Monadic (monadicIO, assert, run)
import Prelude hiding (sequence) import Prelude hiding (sequence)
@ -52,30 +50,6 @@ max_value = 10000
max_length :: Int max_length :: Int
max_length = 1000 max_length = 1000
listEquals :: (Show a, Eq a, MonadIO m)
=> ([a] -> [a] -> Bool) -> [a] -> [a] -> PropertyM m ()
listEquals eq parsed_list list = do
when (not $ parsed_list `eq` list) $ liftIO $ putStrLn $
"parsed list " ++ show parsed_list
++ "\nlist " ++ show list
++ "\nparsed list \\\\ list " ++ show (parsed_list \\ list)
++ "\nlist \\\\ parsed list " ++ show (list \\ parsed_list)
when (not $ parsed_list `eq` list) $
monitor
(counterexample $
"parsed list " ++ show parsed_list
++ "\nlist " ++ show list
++ "\nparsed list \\\\ list " ++ show (parsed_list \\ list)
++ "\nlist \\\\ parsed list " ++ show (list \\ parsed_list)
)
assert (parsed_list `eq` list)
checkListEqual :: (Show a, Eq a) => [a] -> [a] -> Property
checkListEqual ls_1 ls_2 = monadicIO (listEquals (==) ls_1 ls_2)
chooseInt :: (Int, Int) -> Gen Int
chooseInt = choose
-- Accumulator Tests -- Accumulator Tests
fromFold :: Property fromFold :: Property
@ -85,20 +59,6 @@ fromFold =
Right is_equal -> is_equal Right is_equal -> is_equal
Left _ -> False Left _ -> False
any :: Property
any =
forAll (listOf $ chooseInt (min_value, max_value)) $ \ls ->
case S.parse (P.any (> mid_value)) (S.fromList ls) of
Right r -> r == (Prelude.any (> mid_value) ls)
Left _ -> False
all :: Property
all =
forAll (listOf $ chooseInt (min_value, max_value)) $ \ls ->
case S.parse (P.all (> mid_value)) (S.fromList ls) of
Right r -> r == (Prelude.all (> mid_value) ls)
Left _ -> False
yield :: Property yield :: Property
yield = yield =
forAll (chooseInt (min_value, max_value)) $ \x -> forAll (chooseInt (min_value, max_value)) $ \x ->
@ -195,14 +155,6 @@ satisfy =
-- Sequence Parsers Tests -- Sequence Parsers Tests
take :: Property
take =
forAll (chooseInt (min_value, max_value)) $ \n ->
forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
case S.parse (P.take n FL.toList) (S.fromList ls) of
Right parsed_list -> checkListEqual parsed_list (Prelude.take n ls)
Left _ -> property False
takeEQPass :: Property takeEQPass :: Property
takeEQPass = takeEQPass =
forAll (chooseInt (min_value, max_value)) $ \n -> forAll (chooseInt (min_value, max_value)) $ \n ->
@ -268,8 +220,6 @@ nLessThanEqual0 tk ltk =
takeProperties :: Spec takeProperties :: Spec
takeProperties = takeProperties =
describe "take combinators when n <= 0/" $ do describe "take combinators when n <= 0/" $ do
prop "take n FL.toList = []" $
nLessThanEqual0 P.take (\_ -> const [])
prop "takeEQ n FL.toList = []" $ prop "takeEQ n FL.toList = []" $
nLessThanEqual0 P.takeEQ (\_ -> const []) nLessThanEqual0 P.takeEQ (\_ -> const [])
prop "takeGE n FL.toList xs = xs" $ prop "takeGE n FL.toList xs = xs" $
@ -350,25 +300,6 @@ takeWhile1 =
where where
predicate = (== 0) predicate = (== 0)
sliceSepBy :: Property
sliceSepBy =
forAll (listOf (chooseInt (0, 1))) $ \ls ->
case S.parse (P.sliceSepBy predicate FL.toList) (S.fromList ls) of
Right parsed_list -> checkListEqual parsed_list (Prelude.takeWhile (not . predicate) ls)
Left _ -> property False
where
predicate = (== 1)
sliceSepByMax :: Property
sliceSepByMax =
forAll (chooseInt (min_value, max_value)) $ \n ->
forAll (listOf (chooseInt (0, 1))) $ \ls ->
case S.parse (P.sliceSepByMax predicate n FL.toList) (S.fromList ls) of
Right parsed_list -> checkListEqual parsed_list (Prelude.take n (Prelude.takeWhile (not . predicate) ls))
Left _ -> property False
where
predicate = (== 1)
-- splitWithPass :: Property -- splitWithPass :: Property
-- splitWithPass = -- splitWithPass =
-- forAll (listOf (chooseInt (0, 1))) $ \ls -> -- forAll (listOf (chooseInt (0, 1))) $ \ls ->
@ -474,7 +405,8 @@ many =
forAll (listOf (chooseInt (0, 1))) $ \ls -> forAll (listOf (chooseInt (0, 1))) $ \ls ->
let fldstp conL currL = return $ FL.Partial $ conL ++ currL let fldstp conL currL = return $ FL.Partial $ conL ++ currL
concatFold = FL.Fold fldstp (return []) return concatFold = FL.Fold fldstp (return []) return
prsr = P.many concatFold $ P.sliceSepBy (== 1) FL.toList prsr = P.many concatFold
$ P.fromFold $ FL.sliceSepBy (== 1) FL.toList
in in
case S.parse prsr (S.fromList ls) of case S.parse prsr (S.fromList ls) of
Right res_list -> checkListEqual res_list (Prelude.filter (== 0) ls) Right res_list -> checkListEqual res_list (Prelude.filter (== 0) ls)
@ -492,7 +424,8 @@ some =
let let
ls = 0 : genLs ls = 0 : genLs
concatFold = FL.Fold (\concatList curr_list -> return $ FL.Partial $ concatList ++ curr_list) (return []) return concatFold = FL.Fold (\concatList curr_list -> return $ FL.Partial $ concatList ++ curr_list) (return []) return
prsr = P.some concatFold $ P.sliceSepBy (== 1) FL.toList prsr = P.some concatFold
$ P.fromFold $ FL.sliceSepBy (== 1) FL.toList
in in
case S.parse prsr (S.fromList ls) of case S.parse prsr (S.fromList ls) of
Right res_list -> res_list == Prelude.filter (== 0) ls Right res_list -> res_list == Prelude.filter (== 0) ls
@ -515,9 +448,9 @@ applicative =
forAll (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0)) $ \ list1 -> forAll (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0)) $ \ list1 ->
forAll (listOf (chooseAny :: Gen Int)) $ \ list2 -> forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
let parser = let parser =
(,) (,)
<$> P.take (length list1) FL.toList <$> P.fromFold (FL.ltake (length list1) FL.toList)
<*> P.take (length list2) FL.toList <*> P.fromFold (FL.ltake (length list2) FL.toList)
in monadicIO $ do in monadicIO $ do
(olist1, olist2) <- (olist1, olist2) <-
run $ S.parse parser (S.fromList $ list1 ++ list2) run $ S.parse parser (S.fromList $ list1 ++ list2)
@ -529,11 +462,11 @@ applicative =
sequence :: Property sequence :: Property
sequence = sequence =
forAll (vectorOf 11 (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0))) $ \ ins -> forAll (vectorOf 11 (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0))) $ \ ins ->
let parsers = fmap (\xs -> P.take (length xs) FL.toList) ins let p xs = P.fromFold (FL.ltake (length xs) FL.toList)
in monadicIO $ do in monadicIO $ do
outs <- run $ outs <- run $
S.parse S.parse
(Prelude.sequence parsers) (Prelude.sequence $ fmap p ins)
(S.fromList $ concat ins) (S.fromList $ concat ins)
listEquals (==) outs ins listEquals (==) outs ins
@ -544,9 +477,9 @@ monad =
forAll (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0)) $ \ list1 -> forAll (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0)) $ \ list1 ->
forAll (listOf (chooseAny :: Gen Int)) $ \ list2 -> forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
let parser = do let parser = do
olist1 <- P.take (length list1) FL.toList olist1 <- P.fromFold (FL.ltake (length list1) FL.toList)
olist2 <- P.take (length list2) FL.toList olist2 <- P.fromFold (FL.ltake (length list2) FL.toList)
return (olist1, olist2) return (olist1, olist2)
in monadicIO $ do in monadicIO $ do
(olist1, olist2) <- (olist1, olist2) <-
run $ S.parse parser (S.fromList $ list1 ++ list2) run $ S.parse parser (S.fromList $ list1 ++ list2)
@ -562,12 +495,11 @@ parseMany =
forAll (chooseInt (1,100)) $ \len -> forAll (chooseInt (1,100)) $ \len ->
forAll (listOf (vectorOf len (chooseAny :: Gen Int))) $ \ ins -> forAll (listOf (vectorOf len (chooseAny :: Gen Int))) $ \ ins ->
monadicIO $ do monadicIO $ do
outs <- outs <- do
( run let p = P.fromFold $ FL.ltake len FL.toList
$ S.toList run
$ S.parseMany $ S.toList
(P.take len FL.toList) (S.fromList $ concat ins) $ S.parseMany p (S.fromList $ concat ins)
)
listEquals (==) outs ins listEquals (==) outs ins
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -653,8 +585,6 @@ main =
describe "test for accumulator" $ do describe "test for accumulator" $ do
prop "P.fromFold FL.sum = FL.sum" fromFold prop "P.fromFold FL.sum = FL.sum" fromFold
prop "P.any = Prelude.any" Main.any
prop "P.all = Prelude.all" Main.all
prop "yield value provided" yield prop "yield value provided" yield
prop "yield monadic value provided" yieldM prop "yield monadic value provided" yieldM
prop "fail err = Left (SomeException (ParseError err))" parserFail prop "fail err = Left (SomeException (ParseError err))" parserFail
@ -670,7 +600,6 @@ main =
prop "check first element exists and satisfies predicate" satisfy prop "check first element exists and satisfies predicate" satisfy
describe "test for sequence parser" $ do describe "test for sequence parser" $ do
prop "P.take = Prelude.take" Main.take
prop "P.takeEQ = Prelude.take when len >= n" takeEQPass prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
prop "P.takeEQ = Prelude.take when len >= n and fail otherwise" Main.takeEQ prop "P.takeEQ = Prelude.take when len >= n and fail otherwise" Main.takeEQ
prop "P.takeGE n ls = ls when len >= n" takeGEPass prop "P.takeGE n ls = ls when len >= n" takeGEPass
@ -680,8 +609,6 @@ main =
-- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n, else fail" lookAhead -- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n, else fail" lookAhead
prop "P.takeWhile = Prelude.takeWhile" Main.takeWhile prop "P.takeWhile = Prelude.takeWhile" Main.takeWhile
prop "P.takeWhile = Prelude.takeWhile if taken something, else check why failed" takeWhile1 prop "P.takeWhile = Prelude.takeWhile if taken something, else check why failed" takeWhile1
prop "P.sliceSepBy = Prelude.takeWhile (not . predicate)" sliceSepBy
prop "P.sliceSepByMax n predicate = Prelude.take n (Prelude.takeWhile (not . predicate))" sliceSepByMax
-- prop "" splitWithPass -- prop "" splitWithPass
-- prop "" splitWithFailLeft -- prop "" splitWithFailLeft
-- prop "" splitWithFailRight -- prop "" splitWithFailRight

View File

@ -1,17 +1,14 @@
module Main (main) where module Main (main) where
import Control.Exception (SomeException(..)) import Control.Exception (SomeException(..))
import Control.Monad (when)
import Control.Monad.IO.Class (MonadIO(..))
import Data.List ((\\))
import Data.Word (Word8, Word32, Word64) import Data.Word (Word8, Word32, Word64)
import Streamly.Test.Common (listEquals, checkListEqual, chooseInt)
import Test.Hspec (Spec, hspec, describe) import Test.Hspec (Spec, hspec, describe)
import Test.Hspec.QuickCheck import Test.Hspec.QuickCheck
import Test.QuickCheck import Test.QuickCheck
(arbitrary, forAll, choose, elements, Property, (arbitrary, forAll, elements, Property,
property, listOf, vectorOf, counterexample, (.&&.), Gen, suchThat) property, listOf, vectorOf, (.&&.), Gen, suchThat)
import Test.QuickCheck.Monadic import Test.QuickCheck.Monadic (monadicIO, assert, run)
(monadicIO, PropertyM, assert, monitor, run)
import qualified Streamly.Internal.Data.Parser.ParserD as P import qualified Streamly.Internal.Data.Parser.ParserD as P
import qualified Streamly.Internal.Data.Stream.IsStream as S import qualified Streamly.Internal.Data.Stream.IsStream as S
@ -52,30 +49,6 @@ max_value = 10000
max_length :: Int max_length :: Int
max_length = 1000 max_length = 1000
listEquals :: (Show a, Eq a, MonadIO m)
=> ([a] -> [a] -> Bool) -> [a] -> [a] -> PropertyM m ()
listEquals eq parsed_list list = do
when (not $ parsed_list `eq` list) $ liftIO $ putStrLn $
"parsed list " ++ show parsed_list
++ "\nlist " ++ show list
++ "\nparsed list \\\\ list " ++ show (parsed_list \\ list)
++ "\nlist \\\\ parsed list " ++ show (list \\ parsed_list)
when (not $ parsed_list `eq` list) $
monitor
(counterexample $
"parsed list " ++ show parsed_list
++ "\nlist " ++ show list
++ "\nparsed list \\\\ list " ++ show (parsed_list \\ list)
++ "\nlist \\\\ parsed list " ++ show (list \\ parsed_list)
)
assert (parsed_list `eq` list)
checkListEqual :: (Show a, Eq a) => [a] -> [a] -> Property
checkListEqual ls_1 ls_2 = monadicIO (listEquals (==) ls_1 ls_2)
chooseInt :: (Int, Int) -> Gen Int
chooseInt = choose
-- Accumulator Tests -- Accumulator Tests
fromFold :: Property fromFold :: Property
@ -87,20 +60,6 @@ fromFold =
Right is_equal -> is_equal Right is_equal -> is_equal
Left _ -> False Left _ -> False
any :: Property
any =
forAll (listOf $ chooseInt (min_value, max_value)) $ \ls ->
case S.parseD (P.any (> mid_value)) (S.fromList ls) of
Right r -> r == (Prelude.any (> mid_value) ls)
Left _ -> False
all :: Property
all =
forAll (listOf $ chooseInt (min_value, max_value)) $ \ls ->
case S.parseD (P.all (> mid_value)) (S.fromList ls) of
Right r -> r == (Prelude.all (> mid_value) ls)
Left _ -> False
yield :: Property yield :: Property
yield = yield =
forAll (chooseInt (min_value, max_value)) $ \x -> forAll (chooseInt (min_value, max_value)) $ \x ->
@ -192,7 +151,7 @@ take :: Property
take = take =
forAll (chooseInt (min_value, max_value)) $ \n -> forAll (chooseInt (min_value, max_value)) $ \n ->
forAll (listOf (chooseInt (min_value, max_value))) $ \ls -> forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
case S.parseD (P.take n FL.toList) (S.fromList ls) of case S.parseD (P.fromFold $ FL.ltake n FL.toList) (S.fromList ls) of
Right parsed_list -> checkListEqual parsed_list (Prelude.take n ls) Right parsed_list -> checkListEqual parsed_list (Prelude.take n ls)
Left _ -> property False Left _ -> property False
@ -261,8 +220,6 @@ nLessThanEqual0 tk ltk =
takeProperties :: Spec takeProperties :: Spec
takeProperties = takeProperties =
describe "take combinators when n <= 0/" $ do describe "take combinators when n <= 0/" $ do
prop "take n FL.toList = []" $
nLessThanEqual0 P.take (\_ -> const [])
prop "takeEQ n FL.toList = []" $ prop "takeEQ n FL.toList = []" $
nLessThanEqual0 P.takeEQ (\_ -> const []) nLessThanEqual0 P.takeEQ (\_ -> const [])
prop "takeGE n FL.toList xs = xs" $ prop "takeGE n FL.toList xs = xs" $
@ -275,7 +232,7 @@ lookAheadPass :: Property
lookAheadPass = lookAheadPass =
forAll (chooseInt (min_value, max_value)) $ \n -> forAll (chooseInt (min_value, max_value)) $ \n ->
let let
takeWithoutConsume = P.lookAhead $ P.take n FL.toList takeWithoutConsume = P.lookAhead $ P.fromFold $ FL.ltake n FL.toList
parseTwice = do parseTwice = do
parsed_list_1 <- takeWithoutConsume parsed_list_1 <- takeWithoutConsume
parsed_list_2 <- takeWithoutConsume parsed_list_2 <- takeWithoutConsume
@ -291,7 +248,7 @@ lookAhead :: Property
lookAhead = lookAhead =
forAll (chooseInt (min_value, max_value)) $ \n -> forAll (chooseInt (min_value, max_value)) $ \n ->
let let
takeWithoutConsume = P.lookAhead $ P.take n FL.toList takeWithoutConsume = P.lookAhead $ P.fromFold $ FL.ltake n FL.toList
parseTwice = do parseTwice = do
parsed_list_1 <- takeWithoutConsume parsed_list_1 <- takeWithoutConsume
parsed_list_2 <- takeWithoutConsume parsed_list_2 <- takeWithoutConsume
@ -333,7 +290,7 @@ takeWhile1 =
sliceSepBy :: Property sliceSepBy :: Property
sliceSepBy = sliceSepBy =
forAll (listOf (chooseInt (0, 1))) $ \ls -> forAll (listOf (chooseInt (0, 1))) $ \ls ->
case S.parseD (P.sliceSepBy predicate FL.toList) (S.fromList ls) of case S.parseD (P.fromFold $ FL.sliceSepBy predicate FL.toList) (S.fromList ls) of
Right parsed_list -> checkListEqual parsed_list (Prelude.takeWhile (not . predicate) ls) Right parsed_list -> checkListEqual parsed_list (Prelude.takeWhile (not . predicate) ls)
Left _ -> property False Left _ -> property False
where where
@ -343,7 +300,7 @@ sliceSepByMax :: Property
sliceSepByMax = sliceSepByMax =
forAll (chooseInt (min_value, max_value)) $ \n -> forAll (chooseInt (min_value, max_value)) $ \n ->
forAll (listOf (chooseInt (0, 1))) $ \ls -> forAll (listOf (chooseInt (0, 1))) $ \ls ->
case S.parseD (P.sliceSepByMax predicate n FL.toList) (S.fromList ls) of case S.parseD (P.fromFold $ FL.sliceSepByMax predicate n FL.toList) (S.fromList ls) of
Right parsed_list -> checkListEqual parsed_list (Prelude.take n (Prelude.takeWhile (not . predicate) ls)) Right parsed_list -> checkListEqual parsed_list (Prelude.take n (Prelude.takeWhile (not . predicate) ls))
Left _ -> property False Left _ -> property False
where where
@ -383,7 +340,7 @@ teeWithPass =
forAll (chooseInt (min_value, max_value)) $ \n -> forAll (chooseInt (min_value, max_value)) $ \n ->
forAll (listOf (chooseInt (0, 1))) $ \ls -> forAll (listOf (chooseInt (0, 1))) $ \ls ->
let let
prsr = P.take n FL.toList prsr = P.fromFold $ FL.ltake n FL.toList
in in
case S.parseD (P.teeWith (,) prsr prsr) (S.fromList ls) of case S.parseD (P.teeWith (,) prsr prsr) (S.fromList ls) of
Right (ls_1, ls_2) -> checkListEqual (Prelude.take n ls) ls_1 .&&. checkListEqual ls_1 ls_2 Right (ls_1, ls_2) -> checkListEqual (Prelude.take n ls) ls_1 .&&. checkListEqual ls_1 ls_2
@ -480,7 +437,7 @@ many =
let fldstp conL currL = return $ FL.Partial (conL ++ currL) let fldstp conL currL = return $ FL.Partial (conL ++ currL)
concatFold = concatFold =
FL.Fold fldstp (return []) return FL.Fold fldstp (return []) return
prsr = P.many concatFold $ P.sliceSepBy (== 1) FL.toList prsr = P.many concatFold $ P.fromFold $ FL.sliceSepBy (== 1) FL.toList
in case S.parseD prsr (S.fromList ls) of in case S.parseD prsr (S.fromList ls) of
Right res_list -> Right res_list ->
checkListEqual res_list (Prelude.filter (== 0) ls) checkListEqual res_list (Prelude.filter (== 0) ls)
@ -498,7 +455,7 @@ some =
$ \ls -> $ \ls ->
let fldstp conL currL = return $ FL.Partial $ conL ++ currL let fldstp conL currL = return $ FL.Partial $ conL ++ currL
concatFold = FL.Fold fldstp (return []) return concatFold = FL.Fold fldstp (return []) return
prsr = P.some concatFold $ P.sliceSepBy (== 1) FL.toList prsr = P.some concatFold $ P.fromFold $ FL.sliceSepBy (== 1) FL.toList
in case S.parseD prsr (S.fromList ls) of in case S.parseD prsr (S.fromList ls) of
Right res_list -> res_list == Prelude.filter (== 0) ls Right res_list -> res_list == Prelude.filter (== 0) ls
Left _ -> False Left _ -> False
@ -521,8 +478,8 @@ applicative =
forAll (listOf (chooseAny :: Gen Int)) $ \ list2 -> forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
let parser = let parser =
(,) (,)
<$> P.take (length list1) FL.toList <$> P.fromFold (FL.ltake (length list1) FL.toList)
<*> P.take (length list2) FL.toList <*> P.fromFold (FL.ltake (length list2) FL.toList)
in monadicIO $ do in monadicIO $ do
(olist1, olist2) <- (olist1, olist2) <-
run $ S.parseD parser (S.fromList $ list1 ++ list2) run $ S.parseD parser (S.fromList $ list1 ++ list2)
@ -534,7 +491,7 @@ applicative =
sequence :: Property sequence :: Property
sequence = sequence =
forAll (vectorOf 11 (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0))) $ \ ins -> forAll (vectorOf 11 (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0))) $ \ ins ->
let parsers = fmap (\xs -> P.take (length xs) FL.toList) ins let parsers = fmap (\xs -> P.fromFold $ FL.ltake (length xs) FL.toList) ins
in monadicIO $ do in monadicIO $ do
outs <- run $ outs <- run $
S.parseD S.parseD
@ -549,8 +506,8 @@ monad =
forAll (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0)) $ \ list1 -> forAll (listOf (chooseAny :: Gen Int) `suchThat` (\x -> length x > 0)) $ \ list1 ->
forAll (listOf (chooseAny :: Gen Int)) $ \ list2 -> forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
let parser = do let parser = do
olist1 <- P.take (length list1) FL.toList olist1 <- P.fromFold (FL.ltake (length list1) FL.toList)
olist2 <- P.take (length list2) FL.toList olist2 <- P.fromFold (FL.ltake (length list2) FL.toList)
return (olist1, olist2) return (olist1, olist2)
in monadicIO $ do in monadicIO $ do
(olist1, olist2) <- (olist1, olist2) <-
@ -571,7 +528,7 @@ parseMany =
( run ( run
$ S.toList $ S.toList
$ S.parseManyD $ S.parseManyD
(P.take len FL.toList) (S.fromList $ concat ins) (P.fromFold $ FL.ltake len FL.toList) (S.fromList $ concat ins)
) )
listEquals (==) outs ins listEquals (==) outs ins
@ -657,8 +614,6 @@ main =
describe "test for accumulator" $ do describe "test for accumulator" $ do
prop "P.fromFold FL.sum = FL.sum" fromFold prop "P.fromFold FL.sum = FL.sum" fromFold
prop "P.any = Prelude.any" Main.any
prop "P.all = Prelude.all" Main.all
prop "yield value provided" yield prop "yield value provided" yield
prop "yield monadic value provided" yieldM prop "yield monadic value provided" yieldM
prop "always fail" die prop "always fail" die