1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE RankNTypes #-}
4{-# LANGUAGE RecordWildCards #-}
5{-# LANGUAGE ScopedTypeVariables #-}
8-- Module : Streamly.Internal.Data.Parse
9-- Copyright : (c) 2019 Composewell Technologies
11-- Maintainer : streamly@composewell.com
12-- Stability : experimental
17module Streamly.Internal.Data.Parse
38 hiding (any, all, takeWhile)
39import Streamly.Internal.Data.Parse.Types (Parse(..), 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
51-- >>> S.parse (PR.any (== 0)) $ S.fromList [1,0,1]
55any :: Monad m => (a -> Bool) -> Parse m a Bool
56any predicate = Parse step initial (return . Right)
58 initial = return False
67-- >>> S.parse (PR.any (== 0)) $ S.fromList [1,0,1]
71all :: Monad m => (a -> Bool) -> Parse m a Bool
72all predicate = Parse step initial (return . Right)
83-------------------------------------------------------------------------------
85-------------------------------------------------------------------------------
87-- | Stops after taking exactly @n@ input elements.
89-- * Stops - after @n@ elements.
90-- * Fails - if the stream ends before it can collect @n@ elements.
92-- >>> S.parse (PR.takeExact 4 FL.toList) $ S.fromList [1,0,1]
93-- > Left "takeExact: Expecting exactly 4 elements, got 3"
97{-# INLINABLE takeExact #-}
98takeExact :: Monad m => Int -> Fold m a b -> Parse m a b
99takeExact n (Fold fstep finitial fextract) = Parse step initial extract
103 initial = (Tuple' 0) <$> finitial
105 step (Tuple' i r) a = do
109 return $ if i1 < n then Back 0 s1 else Halt 0 s1
111 extract (Tuple' i r) = fmap f (fextract r)
116 "takeExact: Expecting exactly " ++ show n
117 ++ " elements, got " ++ show i
124-- | Take at least @n@ input elements, but can collect more.
127-- * Fails - if the stream end before producing @n@ elements.
129-- >>> S.parse (PR.takeAtLeast 4 FL.toList) $ S.fromList [1,0,1]
130-- > Left "takeAtLeast: Expecting at least 4 elements, got only 3"
132-- >>> S.parse (PR.takeAtLeast 4 FL.toList) $ S.fromList [1,0,1,0,1]
133-- > Right [1,0,1,0,1]
137{-# INLINABLE takeAtLeast #-}
138takeAtLeast :: Monad m => Int -> Fold m a b -> Parse m a b
139takeAtLeast n (Fold fstep finitial fextract) = Parse step initial extract
143 initial = (Tuple' 0) <$> finitial
145 step (Tuple' i r) a = do
151 extract (Tuple' i r) = fmap f (fextract r)
156 "takeAtLeast: Expecting at least " ++ show n
157 ++ " elements, got only " ++ show i
164-- | Take until the predicate fails. Does not take the failing element.
166-- * Stops - when the predicate fails.
169-- >>> S.parse (PR.takeWhile (== 0) FL.toList) $ S.fromList [0,0,1,0,1]
174{-# INLINABLE takeWhile #-}
175takeWhile :: Monad m => (a -> Bool) -> Fold m a b -> Parse m a b
176takeWhile predicate (Fold fstep finitial fextract) =
177 Parse step initial extract
184 then Keep 0 <$> fstep s a
185 else return $ Halt 1 s
190-- | Keep taking elements until the predicate succeeds. Drop the succeeding
193-- * Stops - when the predicate succeeds.
196-- >>> S.parse (PR.endOn (== 1) FL.toList) $ S.fromList [0,0,1,0,1]
199-- >>> S.toList $ S.parseChunks (PR.endOn (== 1) FL.toList) $ S.fromList [0,0,1,0,1]
204{-# INLINABLE endOn #-}
205endOn :: Monad m => (a -> Bool) -> Fold m a b -> Parse m a b
206endOn predicate (Fold fstep finitial fextract) =
207 Parse step initial extract
214 then Keep 0 <$> fstep s a
215 else return $ Halt 0 s
220-- | Keep taking elements until the predicate succeeds. Take the succeeding
223-- * Stops - when the predicate succeeds.
228{-# INLINABLE endAfter #-}
231 (a -> Bool) -> Fold m a b -> Parse m a b
234-- | Keep taking elements until the predicate succeeds. Return the succeeding
235-- element back to the input.
237-- * Stops - when the predicate succeeds.
242{-# INLINABLE endBefore #-}
245 (a -> Bool) -> Fold m a b -> Parse m a b
248-- | Distribute the input to a parse and a fold until the parse succeeds or
249-- fails. The parse can be used to decide the termination of the fold.
253finishBy :: Parse m a x -> Fold m a y -> Parse 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