1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE RankNTypes #-}
4{-# LANGUAGE RecordWildCards #-}
5{-# LANGUAGE ScopedTypeVariables #-}
8-- Module : Streamly.Internal.Data.Parser
9-- Copyright : (c) 2020 Composewell Technologies
11-- Maintainer : streamly@composewell.com
12-- Stability : experimental
17module Streamly.Internal.Data.Parser
38 hiding (any, all, takeWhile)
39import Streamly.Internal.Data.Parser.Types (Parser(..), Step(..))
40import Streamly.Internal.Data.Fold.Types (Fold(..))
42import Streamly.Internal.Data.Strict
44-------------------------------------------------------------------------------
46-------------------------------------------------------------------------------
48-- XXX any/all should be terminating folds when we have a terminating fold
52-- >>> S.parse (PR.any (== 0)) $ S.fromList [1,0,1]
56any :: Monad m => (a -> Bool) -> Parser m a Bool
57any predicate = Parser step initial (return . Right)
59 initial = return False
69-- >>> S.parse (PR.all (== 0)) $ S.fromList [1,0,1]
73all :: Monad m => (a -> Bool) -> Parser m a Bool
74all predicate = Parser step initial (return . Right)
85-------------------------------------------------------------------------------
87-------------------------------------------------------------------------------
89-- | Stops after taking exactly @n@ input elements.
91-- * Stops - after @n@ elements.
92-- * Fails - if the stream ends before it can collect @n@ elements.
94-- >>> S.parse (PR.takeExact 4 FL.toList) $ S.fromList [1,0,1]
95-- > Left "takeExact: Expecting exactly 4 elements, got 3"
99{-# INLINABLE takeExact #-}
100takeExact :: Monad m => Int -> Fold m a b -> Parser m a b
101takeExact n (Fold fstep finitial fextract) = Parser step initial extract
105 initial = (Tuple' 0) <$> finitial
107 step (Tuple' i r) a = do
111 return $ if i1 < n then Skip 0 s1 else Stop 0 s1
113 extract (Tuple' i r) = fmap f (fextract r)
118 "takeExact: Expecting exactly " ++ show n
119 ++ " elements, got " ++ show i
126-- | Take at least @n@ input elements, but can collect more.
129-- * Fails - if the stream end before producing @n@ elements.
131-- >>> S.parse (PR.takeAtLeast 4 FL.toList) $ S.fromList [1,0,1]
132-- > Left "takeAtLeast: Expecting at least 4 elements, got only 3"
134-- >>> S.parse (PR.takeAtLeast 4 FL.toList) $ S.fromList [1,0,1,0,1]
135-- > Right [1,0,1,0,1]
139{-# INLINABLE takeAtLeast #-}
140takeAtLeast :: Monad m => Int -> Fold m a b -> Parser m a b
141takeAtLeast n (Fold fstep finitial fextract) = Parser step initial extract
145 initial = (Tuple' 0) <$> finitial
147 step (Tuple' i r) a = do
152 then return $ Skip 0 s1
153 else return $ Yield 0 s1
155 extract (Tuple' i r) = fmap f (fextract r)
160 "takeAtLeast: Expecting at least " ++ show n
161 ++ " elements, got only " ++ show i
168-- | Take until the predicate fails. Does not take the failing element.
170-- * Stops - when the predicate fails.
173-- >>> S.parse (PR.takeWhile (== 0) FL.toList) $ S.fromList [0,0,1,0,1]
178{-# INLINABLE takeWhile #-}
179takeWhile :: Monad m => (a -> Bool) -> Fold m a b -> Parser m a b
180takeWhile predicate (Fold fstep finitial fextract) =
181 Parser step initial extract
188 then Yield 0 <$> fstep s a
189 else return $ Stop 1 s
194-- | Keep taking elements until the predicate succeeds. Drop the succeeding
197-- * Stops - when the predicate succeeds.
200-- >>> S.parse (PR.endOn (== 1) FL.toList) $ S.fromList [0,0,1,0,1]
203-- >>> S.toList $ S.parseChunks (PR.endOn (== 1) FL.toList) $ S.fromList [0,0,1,0,1]
208{-# INLINABLE endOn #-}
209endOn :: Monad m => (a -> Bool) -> Fold m a b -> Parser m a b
210endOn predicate (Fold fstep finitial fextract) =
211 Parser step initial extract
218 then Yield 0 <$> fstep s a
219 else return $ Stop 0 s
224-- | Keep taking elements until the predicate succeeds. Take the succeeding
227-- * Stops - when the predicate succeeds.
232{-# INLINABLE endAfter #-}
235 (a -> Bool) -> Fold m a b -> Parser m a b
238-- | Keep taking elements until the predicate succeeds. Return the succeeding
239-- element back to the input.
241-- * Stops - when the predicate succeeds.
246{-# INLINABLE endBefore #-}
249 (a -> Bool) -> Fold m a b -> Parser m a b
252-- | Distribute the input to a parse and a fold until the parse succeeds or
253-- fails. The parse can be used to decide the termination of the fold.
257finishBy :: Parser m a x -> Fold m a y -> Parser m a (x, y)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list