1{-# LANGUAGE UndecidableInstances #-}
6-- Module : Streamly.Internal.Data.Stream.StreamK
7-- Copyright : (c) 2017 Composewell Technologies
10-- Maintainer : streamly@composewell.com
11-- Stability : experimental
15-- Continuation passing style (CPS) stream implementation. The symbol 'K' below
16-- denotes a function as well as a Kontinuation.
19-- import qualified Streamly.Internal.Data.Stream.StreamK as K
22module Streamly.Internal.Data.Stream.StreamK
27 -- * Construction Primitives
34 -- * Elimination Primitives
38 -- * Transformation Primitives
49 -- ** Specialized Generation
88 -- ** Specialized Folds
117 -- ** By folding (scans)
165 -- ** Transformation comprehensions
168 -- * Semigroup Style Composition
178import Control.Exception (assert)
179import Control.Monad.Catch (MonadThrow, throwM)
180import Control.Monad.Trans.Class (MonadTrans(lift))
181import Control.Monad (void, join)
182import Streamly.Internal.Data.SVar.Type (adaptState, defState)
184import qualified Streamly.Internal.Data.Fold.Type as FL
185import qualified Streamly.Internal.Data.Parser.ParserD.Type as PR
186import qualified Prelude
189 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
190 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
191 maximum, elem, notElem, null, head, tail, init, zipWith, lookup,
192 foldr1, (!!), replicate, reverse, concatMap, iterate, splitAt)
194import Streamly.Internal.Data.Stream.StreamK.Type
199-------------------------------------------------------------------------------
201-------------------------------------------------------------------------------
203{-# INLINE unfoldrM #-}
204unfoldrM :: Monad m => (b -> m (Maybe (a, b))) -> b -> Stream m a
205unfoldrM = unfoldrMWith consM
207-- Generalization of concurrent streams/SVar via unfoldr.
209-- Unfold a value into monadic actions and then run the resulting monadic
210-- actions to generate a stream. Since the step of generating the monadic
211-- action and running them are decoupled we can run the monadic actions
212-- cooncurrently. For example, the seed could be a list of monadic actions or a
213-- pure stream of monadic actions.
215-- We can have different flavors of this depending on the stream type t. The
216-- concurrent version could be async or ahead etc. Depending on how we queue
217-- back the feedback portion b, it could be DFS or BFS style.
219unfoldrA :: (IsStream t, MonadAsync m) =>
220 (b -> Maybe (m a, b)) -> b -> Stream m a
224-------------------------------------------------------------------------------
226-------------------------------------------------------------------------------
228repeatM :: Monad m => m a -> Stream m a
229repeatM = repeatMWith consM
231{-# INLINE replicateM #-}
232replicateM :: Monad m => Int -> m a -> Stream m a
233replicateM = replicateMWith consM
234{-# INLINE replicate #-}
235replicate :: Int -> a -> Stream m a
238 go cnt = if cnt <= 0 then nil else a `cons` go (cnt - 1)
240{-# INLINE fromIndicesM #-}
241fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
242fromIndicesM = fromIndicesMWith consM
243{-# INLINE fromIndices #-}
244fromIndices :: (Int -> a) -> Stream m a
245fromIndices gen = go 0
247 go n = gen n `cons` go (n + 1)
249{-# INLINE iterate #-}
250iterate :: (a -> a) -> a -> Stream m a
253 go !s = cons s (go (step s))
255{-# INLINE iterateM #-}
256iterateM :: Monad m => (a -> m a) -> m a -> Stream m a
257iterateM = iterateMWith consM
259-------------------------------------------------------------------------------
261-------------------------------------------------------------------------------
263{-# INLINE fromList #-}
264fromList :: [a] -> Stream m a
265fromList = fromFoldable
267-------------------------------------------------------------------------------
268-- Elimination by Folding
269-------------------------------------------------------------------------------
271-- | Lazy right associative fold.
273foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b
274foldr step acc = foldrM (\x xs -> xs >>= \b -> return (step x b)) (return acc)
276-- | Right associative fold to an arbitrary transformer monad.
278foldrT :: (Monad m, Monad (s m), MonadTrans s)
279 => (a -> s m b -> s m b) -> s m b -> Stream m a -> s m b
280foldrT step final = go
283 res <- lift $ uncons m1
285 Just (h, t) -> step h (go t)
289foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
293 Nothing -> return Nothing
294 Just (h, t) -> fmap Just (go h t)
298 single a = return $ step a p
299 yieldk a r = fmap (step p) (go a r)
300 in foldStream defState yieldk single stp m1
302-- XXX replace the recursive "go" with explicit continuations.
303-- | Like 'foldx', but with a monadic step function.
304{-# INLINABLE foldlMx' #-}
306 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> m b
307foldlMx' step begin done = go begin
310 let stop = acc >>= done
311 single a = acc >>= \b -> step b a >>= done
312 yieldk a r = acc >>= \b -> step b a >>= \x -> go (return x) r
313 in foldStream defState yieldk single stop m1
315{-# INLINABLE fold #-}
316fold :: Monad m => FL.Fold m a b -> Stream m a -> m b
317fold (FL.Fold step begin done) m = do
320 FL.Partial fs -> go fs m
321 FL.Done fb -> return fb
326 single a = step acc a
328 FL.Partial s -> done s
329 FL.Done b1 -> return b1
330 yieldk a r = step acc a
332 FL.Partial s -> go s r
333 FL.Done b1 -> return b1
334 in foldStream defState yieldk single stop m1
336{-# INLINE foldBreak #-}
337foldBreak :: Monad m => FL.Fold m a b -> Stream m a -> m (b, Stream m a)
338foldBreak (FL.Fold step begin done) m = do
341 FL.Partial fs -> go fs m
342 FL.Done fb -> return (fb, m)
347 let stop = (, nil) <$> done acc
351 FL.Partial s -> (, nil) <$> done s
352 FL.Done b1 -> return (b1, nil)
356 FL.Partial s -> go s r
357 FL.Done b1 -> return (b1, r)
358 in foldStream defState yieldk single stop m1
360-- | Like 'foldl'' but with a monadic step function.
361{-# INLINE foldlM' #-}
362foldlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> m b
363foldlM' step begin = foldlMx' step begin return
365-- | Lazy left fold to an arbitrary transformer monad.
367foldlT :: (Monad m, Monad (s m), MonadTrans s)
368 => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
372 res <- lift $ uncons m1
374 Just (h, t) -> go (step acc h) t
377------------------------------------------------------------------------------
379------------------------------------------------------------------------------
382head :: Monad m => Stream m a -> m (Maybe a)
383-- head = foldrM (\x _ -> return $ Just x) (return Nothing)
385 let stop = return Nothing
386 single a = return (Just a)
387 yieldk a _ = return (Just a)
388 in foldStream defState yieldk single stop m
391elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
395 let stop = return False
396 single a = return (a == e)
397 yieldk a r = if a == e then return True else go r
398 in foldStream defState yieldk single stop m1
400{-# INLINE notElem #-}
401notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
405 let stop = return True
406 single a = return (a /= e)
407 yieldk a r = if a == e then return False else go r
408 in foldStream defState yieldk single stop m1
411all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
415 let single a | p a = return True
416 | otherwise = return False
417 yieldk a r | p a = go r
418 | otherwise = return False
419 in foldStream defState yieldk single (return True) m1
422any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
426 let single a | p a = return True
427 | otherwise = return False
428 yieldk a r | p a = return True
430 in foldStream defState yieldk single (return False) m1
432-- | Extract the last element of the stream, if any.
434last :: Monad m => Stream m a -> m (Maybe a)
435last = foldlx' (\_ y -> Just y) Nothing id
437{-# INLINE minimum #-}
438minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
442 let stop = return Nothing
443 single a = return (Just a)
444 yieldk a r = go (Just a) r
445 in foldStream defState yieldk single stop m1
448 let stop = return (Just res)
451 then return (Just res)
457 in foldStream defState yieldk single stop m1
459{-# INLINE minimumBy #-}
462 => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
463minimumBy cmp = go Nothing
466 let stop = return Nothing
467 single a = return (Just a)
468 yieldk a r = go (Just a) r
469 in foldStream defState yieldk single stop m1
472 let stop = return (Just res)
473 single a = case cmp res a of
474 GT -> return (Just a)
475 _ -> return (Just res)
476 yieldk a r = case cmp res a of
479 in foldStream defState yieldk single stop m1
481{-# INLINE maximum #-}
482maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
486 let stop = return Nothing
487 single a = return (Just a)
488 yieldk a r = go (Just a) r
489 in foldStream defState yieldk single stop m1
492 let stop = return (Just res)
496 else return (Just res)
501 in foldStream defState yieldk single stop m1
503{-# INLINE maximumBy #-}
504maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
505maximumBy cmp = go Nothing
508 let stop = return Nothing
509 single a = return (Just a)
510 yieldk a r = go (Just a) r
511 in foldStream defState yieldk single stop m1
514 let stop = return (Just res)
515 single a = case cmp res a of
516 GT -> return (Just res)
518 yieldk a r = case cmp res a of
519 GT -> go (Just res) r
521 in foldStream defState yieldk single stop m1
524(!!) :: Monad m => Stream m a -> Int -> m (Maybe a)
528 let single a | n == 0 = return $ Just a
529 | otherwise = return Nothing
530 yieldk a x | n < 0 = return Nothing
531 | n == 0 = return $ Just a
532 | otherwise = go (n - 1) x
533 in foldStream defState yieldk single (return Nothing) m1
536lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
540 let single (a, b) | a == e = return $ Just b
541 | otherwise = return Nothing
542 yieldk (a, b) x | a == e = return $ Just b
544 in foldStream defState yieldk single (return Nothing) m1
547findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
553 if b then return $ Just a else return Nothing
556 if b then return $ Just a else go x
557 in foldStream defState yieldk single (return Nothing) m1
560find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
561find p = findM (return . p)
563{-# INLINE findIndices #-}
564findIndices :: (a -> Bool) -> Stream m a -> Stream m Int
567 go offset m1 = mkStream $ \st yld sng stp ->
568 let single a | p a = sng offset
570 yieldk a x | p a = yld offset $ go (offset + 1) x
571 | otherwise = foldStream (adaptState st) yld sng stp $
573 in foldStream (adaptState st) yieldk single stp m1
575------------------------------------------------------------------------------
577------------------------------------------------------------------------------
579-- | Apply a monadic action to each element of the stream and discard the
580-- output of the action.
582mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
587 single a = void (f a)
588 yieldk a r = f a >> go r
589 in foldStream defState yieldk single stop m1
592mapM :: Monad m => (a -> m b) -> Stream m a -> Stream m b
595------------------------------------------------------------------------------
597------------------------------------------------------------------------------
599{-# INLINABLE toList #-}
600toList :: Monad m => Stream m a -> m [a]
603-- Based on suggestions by David Feuer and Pranay Sashank
605hoist :: (Monad m, Monad n)
606 => (forall x. m x -> n x) -> Stream m a -> Stream n a
608 mkStream $ \st yld sng stp ->
609 let single = return . sng
610 yieldk a s = return $ yld a (hoist f s)
612 state = adaptState st
613 in join . f $ foldStreamShared state yieldk single stop str
615-------------------------------------------------------------------------------
616-- Transformation by folding (Scans)
617-------------------------------------------------------------------------------
619{-# INLINE scanlx' #-}
620scanlx' :: (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
621scanlx' step begin done m =
622 cons (done begin) $ go m begin
624 go m1 !acc = mkStream $ \st yld sng stp ->
625 let single a = sng (done $ step acc a)
628 in yld (done s) (go r s)
629 in foldStream (adaptState st) yieldk single stp m1
632scanl' :: (b -> a -> b) -> b -> Stream m a -> Stream m b
633scanl' step begin = scanlx' step begin id
635-------------------------------------------------------------------------------
637-------------------------------------------------------------------------------
640filter :: (a -> Bool) -> Stream m a -> Stream m a
643 go m1 = mkStream $ \st yld sng stp ->
644 let single a | p a = sng a
646 yieldk a r | p a = yld a (go r)
647 | otherwise = foldStream st yieldk single stp r
648 in foldStream st yieldk single stp m1
651take :: Int -> Stream m a -> Stream m a
654 go n1 m1 = mkStream $ \st yld sng stp ->
655 let yieldk a r = yld a (go (n1 - 1) r)
658 else foldStream st yieldk sng stp m1
660{-# INLINE takeWhile #-}
661takeWhile :: (a -> Bool) -> Stream m a -> Stream m a
664 go m1 = mkStream $ \st yld sng stp ->
665 let single a | p a = sng a
667 yieldk a r | p a = yld a (go r)
669 in foldStream st yieldk single stp m1
672drop :: Int -> Stream m a -> Stream m a
673drop n m = unShare (go n m)
675 go n1 m1 = mkStream $ \st yld sng stp ->
677 yieldk _ r = foldStreamShared st yld sng stp $ go (n1 - 1) r
678 -- Somehow "<=" check performs better than a ">"
680 then foldStreamShared st yld sng stp m1
681 else foldStreamShared st yieldk single stp m1
683{-# INLINE dropWhile #-}
684dropWhile :: (a -> Bool) -> Stream m a -> Stream m a
687 go m1 = mkStream $ \st yld sng stp ->
688 let single a | p a = stp
690 yieldk a r | p a = foldStream st yieldk single stp r
691 | otherwise = yld a r
692 in foldStream st yieldk single stp m1
694-------------------------------------------------------------------------------
696-------------------------------------------------------------------------------
698-- Be careful when modifying this, this uses a consM (|:) deliberately to allow
699-- other stream types to overload it.
700{-# INLINE sequence #-}
701sequence :: Monad m => Stream m (m a) -> Stream m a
704 go m1 = mkStream $ \st yld sng stp ->
705 let single ma = ma >>= sng
706 yieldk ma r = foldStreamShared st yld sng stp $ ma `consM` go r
707 in foldStream (adaptState st) yieldk single stp m1
709-------------------------------------------------------------------------------
711-------------------------------------------------------------------------------
713{-# INLINE intersperseM #-}
714intersperseM :: Monad m => m a -> Stream m a -> Stream m a
715intersperseM a = prependingStart
717 prependingStart m1 = mkStream $ \st yld sng stp ->
719 foldStreamShared st yld sng stp $ return i `consM` go x
720 in foldStream st yieldk sng stp m1
721 go m2 = mkStream $ \st yld sng stp ->
722 let single i = foldStreamShared st yld sng stp $ a `consM` fromPure i
725 st yld sng stp $ a `consM` return i `consM` go x
726 in foldStream st yieldk single stp m2
728{-# INLINE intersperse #-}
729intersperse :: Monad m => a -> Stream m a -> Stream m a
730intersperse a = intersperseM (return a)
732{-# INLINE insertBy #-}
733insertBy :: (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
736 go m1 = mkStream $ \st yld _ _ ->
737 let single a = case cmp x a of
738 GT -> yld a (fromPure x)
739 _ -> yld x (fromPure a)
741 yieldk a r = case cmp x a of
743 _ -> yld x (a `cons` r)
744 in foldStream st yieldk single stop m1
746------------------------------------------------------------------------------
748------------------------------------------------------------------------------
750{-# INLINE deleteBy #-}
751deleteBy :: (a -> a -> Bool) -> a -> Stream m a -> Stream m a
754 go m1 = mkStream $ \st yld sng stp ->
755 let single a = if eq x a then stp else sng a
756 yieldk a r = if eq x a
757 then foldStream st yld sng stp r
759 in foldStream st yieldk single stp m1
761-------------------------------------------------------------------------------
763-------------------------------------------------------------------------------
765{-# INLINE mapMaybe #-}
766mapMaybe :: (a -> Maybe b) -> Stream m a -> Stream m b
769 go m1 = mkStream $ \st yld sng stp ->
770 let single a = maybe stp sng (f a)
771 yieldk a r = case f a of
772 Just b -> yld b $ go r
773 Nothing -> foldStream (adaptState st) yieldk single stp r
774 in foldStream (adaptState st) yieldk single stp m1
776------------------------------------------------------------------------------
778------------------------------------------------------------------------------
780-- | Zip two streams serially using a pure zipping function.
783{-# INLINE zipWith #-}
784zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
785zipWith f = zipWithM (\a b -> return (f a b))
787-- | Zip two streams serially using a monadic zipping function.
790{-# INLINE zipWithM #-}
791zipWithM :: Monad m =>
792 (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
797 go mx my = mkStream $ \st yld sng stp -> do
799 let single2 b = f a b >>= sng
800 yield2 b rb = f a b >>= \x -> yld x (go ra rb)
801 in foldStream (adaptState st) yield2 single2 stp my
802 let single1 a = merge a nil
804 foldStream (adaptState st) yield1 single1 stp mx
806------------------------------------------------------------------------------
808------------------------------------------------------------------------------
810{-# INLINE mergeByM #-}
811mergeByM :: Monad m =>
812 (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
817 go mx my = mkStream $ \st yld sng stp -> do
818 let stop = foldStream st yld sng stp my
819 single x = foldStream st yld sng stp (goX0 x my)
820 yield x rx = foldStream st yld sng stp (goX x rx my)
821 foldStream st yield single stop mx
823 goX0 x my = mkStream $ \st yld sng _ -> do
828 GT -> yld y (fromPure x)
829 _ -> yld x (fromPure y)
833 GT -> yld y (goX0 x ry)
834 _ -> yld x (y `cons` ry)
835 in foldStream st yield single stop my
837 goX x mx my = mkStream $ \st yld _ _ -> do
842 GT -> yld y (x `cons` mx)
843 _ -> yld x (goY0 mx y)
847 GT -> yld y (goX x mx ry)
848 _ -> yld x (goY mx y ry)
849 in foldStream st yield single stop my
851 goY0 mx y = mkStream $ \st yld sng _ -> do
856 GT -> yld y (fromPure x)
857 _ -> yld x (fromPure y)
861 GT -> yld y (x `cons` rx)
862 _ -> yld x (goY0 rx y)
863 in foldStream st yield single stop mx
865 goY mx y my = mkStream $ \st yld _ _ -> do
870 GT -> yld y (goX0 x my)
871 _ -> yld x (y `cons` my)
875 GT -> yld y (goX x rx my)
876 _ -> yld x (goY rx y my)
877 in foldStream st yield single stop mx
879{-# INLINE mergeBy #-}
880mergeBy :: (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
881-- XXX GHC: This has slightly worse performance than replacing "r <- cmp x y"
882-- with "let r = cmp x y" in the monadic version. The definition below is
883-- exactly the same as mergeByM except this change.
884-- mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
889 go mx my = mkStream $ \st yld sng stp -> do
890 let stop = foldStream st yld sng stp my
891 single x = foldStream st yld sng stp (goX0 x my)
892 yield x rx = foldStream st yld sng stp (goX x rx my)
893 foldStream st yield single stop mx
895 goX0 x my = mkStream $ \st yld sng _ -> do
899 GT -> yld y (fromPure x)
900 _ -> yld x (fromPure y)
903 GT -> yld y (goX0 x ry)
904 _ -> yld x (y `cons` ry)
905 in foldStream st yield single stop my
907 goX x mx my = mkStream $ \st yld _ _ -> do
911 GT -> yld y (x `cons` mx)
912 _ -> yld x (goY0 mx y)
915 GT -> yld y (goX x mx ry)
916 _ -> yld x (goY mx y ry)
917 in foldStream st yield single stop my
919 goY0 mx y = mkStream $ \st yld sng _ -> do
923 GT -> yld y (fromPure x)
924 _ -> yld x (fromPure y)
927 GT -> yld y (x `cons` rx)
928 _ -> yld x (goY0 rx y)
929 in foldStream st yield single stop mx
931 goY mx y my = mkStream $ \st yld _ _ -> do
935 GT -> yld y (goX0 x my)
936 _ -> yld x (y `cons` my)
939 GT -> yld y (goX x rx my)
940 _ -> yld x (goY rx y my)
941 in foldStream st yield single stop mx
943------------------------------------------------------------------------------
944-- Transformation comprehensions
945------------------------------------------------------------------------------
948the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
952 Nothing -> return Nothing
953 Just (h, t) -> go h t
956 let single a | h == a = return $ Just h
957 | otherwise = return Nothing
958 yieldk a r | h == a = go h r
959 | otherwise = return Nothing
960 in foldStream defState yieldk single (return $ Just h) m1
962------------------------------------------------------------------------------
963-- Alternative & MonadPlus
964------------------------------------------------------------------------------
966_alt :: Stream m a -> Stream m a -> Stream m a
967_alt m1 m2 = mkStream $ \st yld sng stp ->
968 let stop = foldStream st yld sng stp m2
969 in foldStream st yld sng stop m1
971------------------------------------------------------------------------------
973------------------------------------------------------------------------------
976-- XXX handle and test cross thread state transfer
979 => Stream m a -> (e -> Stream m a) -> Stream m a
981 mkStream $ \_ stp sng yld ->
982 let run x = unStream x Nothing stp sng yieldk
983 handle r = r `catchError` \e -> run $ h e
984 yieldk a r = yld a (withCatchError r h)
988-------------------------------------------------------------------------------
990-------------------------------------------------------------------------------
992-- Inlined definition.
993{-# INLINE splitAt #-}
994splitAt :: Int -> [a] -> ([a],[a])
997 | otherwise = splitAt' n ls
999 splitAt' :: Int -> [a] -> ([a], [a])
1000 splitAt' _ [] = ([], [])
1001 splitAt' 1 (x:xs) = ([x], xs)
1002 splitAt' m (x:xs) = (x:xs', xs'')
1004 (xs', xs'') = splitAt' (m - 1) xs
1006-- | Run a 'Parser' over a stream and return rest of the Stream.
1007{-# INLINE_NORMAL parseBreak #-}
1012 -> m (b, Stream m a)
1013parseBreak (PR.Parser pstep initial extract) stream = do
1016 PR.IPartial s -> goStream stream [] s
1017 PR.IDone b -> return (b, stream)
1018 PR.IError err -> throwM $ PR.ParseError err
1022 -- "buf" contains last few items in the stream that we may have to
1025 -- XXX currently we are using a dumb list based approach for backtracking
1026 -- buffer. This can be replaced by a sliding/ring buffer using Data.Array.
1027 -- That will allow us more efficient random back and forth movement.
1028 goStream st buf !pst =
1031 return (b, fromList buf)
1032 single x = yieldk x nil
1036 PR.Partial 0 s -> goStream r [] s
1037 PR.Partial n s -> do
1038 assert (n <= length (x:buf)) (return ())
1039 let src0 = Prelude.take n (x:buf)
1040 src = Prelude.reverse src0
1042 PR.Continue 0 s -> goStream r (x:buf) s
1043 PR.Continue n s -> do
1044 assert (n <= length (x:buf)) (return ())
1045 let (src0, buf1) = splitAt n (x:buf)
1046 src = Prelude.reverse src0
1048 PR.Done 0 b -> return (b, r)
1050 assert (n <= length (x:buf)) (return ())
1051 let src0 = Prelude.take n (x:buf)
1052 src = Prelude.reverse src0
1053 return (b, serial (fromList src) r)
1054 PR.Error err -> throwM $ PR.ParseError err
1055 in foldStream defState yieldk single stop st
1057 goBuf st buf [] !pst = goStream st buf pst
1058 goBuf st buf (x:xs) !pst = do
1061 PR.Partial 0 s -> goBuf st [] xs s
1062 PR.Partial n s -> do
1063 assert (n <= length (x:buf)) (return ())
1064 let src0 = Prelude.take n (x:buf)
1065 src = Prelude.reverse src0 ++ xs
1067 PR.Continue 0 s -> goBuf st (x:buf) xs s
1068 PR.Continue n s -> do
1069 assert (n <= length (x:buf)) (return ())
1070 let (src0, buf1) = splitAt n (x:buf)
1071 src = Prelude.reverse src0 ++ xs
1074 assert (n <= length (x:buf)) (return ())
1075 let src0 = Prelude.take n (x:buf)
1076 src = Prelude.reverse src0
1077 return (b, serial (fromList src) st)
1078 PR.Error err -> throwM $ PR.ParseError err
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