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
180import Control.Monad.Catch (MonadThrow, throwM)
181import Control.Monad.Trans.Class (MonadTrans(lift))
182import Control.Monad (void, join)
183import Streamly.Internal.Data.SVar.Type (adaptState, defState)
185import qualified Streamly.Internal.Data.Fold.Type as FL
186import qualified Streamly.Internal.Data.Parser.ParserD.Type as PR
187import qualified Prelude
190 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
191 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
192 maximum, elem, notElem, null, head, tail, init, zipWith, lookup,
193 foldr1, (!!), replicate, reverse, concatMap, iterate, splitAt)
195import Streamly.Internal.Data.Stream.StreamK.Type
200-------------------------------------------------------------------------------
202-------------------------------------------------------------------------------
204{-# INLINE unfoldrM #-}
205unfoldrM :: Monad m => (b -> m (Maybe (a, b))) -> b -> Stream m a
206unfoldrM = unfoldrMWith consM
208-- Generalization of concurrent streams/SVar via unfoldr.
210-- Unfold a value into monadic actions and then run the resulting monadic
211-- actions to generate a stream. Since the step of generating the monadic
212-- action and running them are decoupled we can run the monadic actions
213-- cooncurrently. For example, the seed could be a list of monadic actions or a
214-- pure stream of monadic actions.
216-- We can have different flavors of this depending on the stream type t. The
217-- concurrent version could be async or ahead etc. Depending on how we queue
218-- back the feedback portion b, it could be DFS or BFS style.
220unfoldrA :: (IsStream t, MonadAsync m) =>
221 (b -> Maybe (m a, b)) -> b -> Stream m a
225-------------------------------------------------------------------------------
227-------------------------------------------------------------------------------
229repeatM :: Monad m => m a -> Stream m a
230repeatM = repeatMWith consM
232{-# INLINE replicateM #-}
233replicateM :: Monad m => Int -> m a -> Stream m a
234replicateM = replicateMWith consM
235{-# INLINE replicate #-}
236replicate :: Int -> a -> Stream m a
239 go cnt = if cnt <= 0 then nil else a `cons` go (cnt - 1)
241{-# INLINE fromIndicesM #-}
242fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
243fromIndicesM = fromIndicesMWith consM
244{-# INLINE fromIndices #-}
245fromIndices :: (Int -> a) -> Stream m a
246fromIndices gen = go 0
248 go n = gen n `cons` go (n + 1)
250{-# INLINE iterate #-}
251iterate :: (a -> a) -> a -> Stream m a
254 go !s = cons s (go (step s))
256{-# INLINE iterateM #-}
257iterateM :: Monad m => (a -> m a) -> m a -> Stream m a
258iterateM = iterateMWith consM
260-------------------------------------------------------------------------------
262-------------------------------------------------------------------------------
264{-# INLINE fromList #-}
265fromList :: [a] -> Stream m a
266fromList = fromFoldable
268-------------------------------------------------------------------------------
269-- Elimination by Folding
270-------------------------------------------------------------------------------
272-- | Lazy right associative fold.
274foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b
275foldr step acc = foldrM (\x xs -> xs >>= \b -> return (step x b)) (return acc)
277-- | Right associative fold to an arbitrary transformer monad.
279foldrT :: (Monad m, Monad (s m), MonadTrans s)
280 => (a -> s m b -> s m b) -> s m b -> Stream m a -> s m b
281foldrT step final = go
284 res <- lift $ uncons m1
286 Just (h, t) -> step h (go t)
290foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
294 Nothing -> return Nothing
295 Just (h, t) -> fmap Just (go h t)
299 single a = return $ step a p
300 yieldk a r = fmap (step p) (go a r)
301 in foldStream defState yieldk single stp m1
303-- XXX replace the recursive "go" with explicit continuations.
304-- | Like 'foldx', but with a monadic step function.
305{-# INLINABLE foldlMx' #-}
307 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> m b
308foldlMx' step begin done = go begin
311 let stop = acc >>= done
312 single a = acc >>= \b -> step b a >>= done
313 yieldk a r = acc >>= \b -> step b a >>= \x -> go (return x) r
314 in foldStream defState yieldk single stop m1
316{-# INLINABLE fold #-}
317fold :: Monad m => FL.Fold m a b -> Stream m a -> m b
318fold (FL.Fold step begin done) m = do
321 FL.Partial fs -> go fs m
322 FL.Done fb -> return fb
327 single a = step acc a
329 FL.Partial s -> done s
330 FL.Done b1 -> return b1
331 yieldk a r = step acc a
333 FL.Partial s -> go s r
334 FL.Done b1 -> return b1
335 in foldStream defState yieldk single stop m1
337{-# INLINE foldBreak #-}
338foldBreak :: Monad m => FL.Fold m a b -> Stream m a -> m (b, Stream m a)
339foldBreak (FL.Fold step begin done) m = do
342 FL.Partial fs -> go fs m
343 FL.Done fb -> return (fb, m)
348 let stop = (, nil) <$> done acc
352 FL.Partial s -> (, nil) <$> done s
353 FL.Done b1 -> return (b1, nil)
357 FL.Partial s -> go s r
358 FL.Done b1 -> return (b1, r)
359 in foldStream defState yieldk single stop m1
361-- | Like 'foldl'' but with a monadic step function.
362{-# INLINE foldlM' #-}
363foldlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> m b
364foldlM' step begin = foldlMx' step begin return
366-- | Lazy left fold to an arbitrary transformer monad.
368foldlT :: (Monad m, Monad (s m), MonadTrans s)
369 => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
373 res <- lift $ uncons m1
375 Just (h, t) -> go (step acc h) t
378------------------------------------------------------------------------------
380------------------------------------------------------------------------------
383head :: Monad m => Stream m a -> m (Maybe a)
384-- head = foldrM (\x _ -> return $ Just x) (return Nothing)
386 let stop = return Nothing
387 single a = return (Just a)
388 yieldk a _ = return (Just a)
389 in foldStream defState yieldk single stop m
392elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
396 let stop = return False
397 single a = return (a == e)
398 yieldk a r = if a == e then return True else go r
399 in foldStream defState yieldk single stop m1
401{-# INLINE notElem #-}
402notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
406 let stop = return True
407 single a = return (a /= e)
408 yieldk a r = if a == e then return False else go r
409 in foldStream defState yieldk single stop m1
412all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
416 let single a | p a = return True
417 | otherwise = return False
418 yieldk a r | p a = go r
419 | otherwise = return False
420 in foldStream defState yieldk single (return True) m1
423any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
427 let single a | p a = return True
428 | otherwise = return False
429 yieldk a r | p a = return True
431 in foldStream defState yieldk single (return False) m1
433-- | Extract the last element of the stream, if any.
435last :: Monad m => Stream m a -> m (Maybe a)
436last = foldlx' (\_ y -> Just y) Nothing id
438{-# INLINE minimum #-}
439minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
443 let stop = return Nothing
444 single a = return (Just a)
445 yieldk a r = go (Just a) r
446 in foldStream defState yieldk single stop m1
449 let stop = return (Just res)
452 then return (Just res)
458 in foldStream defState yieldk single stop m1
460{-# INLINE minimumBy #-}
463 => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
464minimumBy cmp = go Nothing
467 let stop = return Nothing
468 single a = return (Just a)
469 yieldk a r = go (Just a) r
470 in foldStream defState yieldk single stop m1
473 let stop = return (Just res)
474 single a = case cmp res a of
475 GT -> return (Just a)
476 _ -> return (Just res)
477 yieldk a r = case cmp res a of
480 in foldStream defState yieldk single stop m1
482{-# INLINE maximum #-}
483maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
487 let stop = return Nothing
488 single a = return (Just a)
489 yieldk a r = go (Just a) r
490 in foldStream defState yieldk single stop m1
493 let stop = return (Just res)
497 else return (Just res)
502 in foldStream defState yieldk single stop m1
504{-# INLINE maximumBy #-}
505maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
506maximumBy cmp = go Nothing
509 let stop = return Nothing
510 single a = return (Just a)
511 yieldk a r = go (Just a) r
512 in foldStream defState yieldk single stop m1
515 let stop = return (Just res)
516 single a = case cmp res a of
517 GT -> return (Just res)
519 yieldk a r = case cmp res a of
520 GT -> go (Just res) r
522 in foldStream defState yieldk single stop m1
525(!!) :: Monad m => Stream m a -> Int -> m (Maybe a)
529 let single a | n == 0 = return $ Just a
530 | otherwise = return Nothing
531 yieldk a x | n < 0 = return Nothing
532 | n == 0 = return $ Just a
533 | otherwise = go (n - 1) x
534 in foldStream defState yieldk single (return Nothing) m1
537lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
541 let single (a, b) | a == e = return $ Just b
542 | otherwise = return Nothing
543 yieldk (a, b) x | a == e = return $ Just b
545 in foldStream defState yieldk single (return Nothing) m1
548findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
554 if b then return $ Just a else return Nothing
557 if b then return $ Just a else go x
558 in foldStream defState yieldk single (return Nothing) m1
561find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
562find p = findM (return . p)
564{-# INLINE findIndices #-}
565findIndices :: (a -> Bool) -> Stream m a -> Stream m Int
568 go offset m1 = mkStream $ \st yld sng stp ->
569 let single a | p a = sng offset
571 yieldk a x | p a = yld offset $ go (offset + 1) x
572 | otherwise = foldStream (adaptState st) yld sng stp $
574 in foldStream (adaptState st) yieldk single stp m1
576------------------------------------------------------------------------------
578------------------------------------------------------------------------------
580-- | Apply a monadic action to each element of the stream and discard the
581-- output of the action.
583mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
588 single a = void (f a)
589 yieldk a r = f a >> go r
590 in foldStream defState yieldk single stop m1
593mapM :: Monad m => (a -> m b) -> Stream m a -> Stream m b
596------------------------------------------------------------------------------
598------------------------------------------------------------------------------
600{-# INLINABLE toList #-}
601toList :: Monad m => Stream m a -> m [a]
604-- Based on suggestions by David Feuer and Pranay Sashank
606hoist :: (Monad m, Monad n)
607 => (forall x. m x -> n x) -> Stream m a -> Stream n a
609 mkStream $ \st yld sng stp ->
610 let single = return . sng
611 yieldk a s = return $ yld a (hoist f s)
613 state = adaptState st
614 in join . f $ foldStreamShared state yieldk single stop str
616-------------------------------------------------------------------------------
617-- Transformation by folding (Scans)
618-------------------------------------------------------------------------------
620{-# INLINE scanlx' #-}
621scanlx' :: (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
622scanlx' step begin done m =
623 cons (done begin) $ go m begin
625 go m1 !acc = mkStream $ \st yld sng stp ->
626 let single a = sng (done $ step acc a)
629 in yld (done s) (go r s)
630 in foldStream (adaptState st) yieldk single stp m1
633scanl' :: (b -> a -> b) -> b -> Stream m a -> Stream m b
634scanl' step begin = scanlx' step begin id
636-------------------------------------------------------------------------------
638-------------------------------------------------------------------------------
641filter :: (a -> Bool) -> Stream m a -> Stream m a
644 go m1 = mkStream $ \st yld sng stp ->
645 let single a | p a = sng a
647 yieldk a r | p a = yld a (go r)
648 | otherwise = foldStream st yieldk single stp r
649 in foldStream st yieldk single stp m1
652take :: Int -> Stream m a -> Stream m a
655 go n1 m1 = mkStream $ \st yld sng stp ->
656 let yieldk a r = yld a (go (n1 - 1) r)
659 else foldStream st yieldk sng stp m1
661{-# INLINE takeWhile #-}
662takeWhile :: (a -> Bool) -> Stream m a -> Stream m a
665 go m1 = mkStream $ \st yld sng stp ->
666 let single a | p a = sng a
668 yieldk a r | p a = yld a (go r)
670 in foldStream st yieldk single stp m1
673drop :: Int -> Stream m a -> Stream m a
674drop n m = unShare (go n m)
676 go n1 m1 = mkStream $ \st yld sng stp ->
678 yieldk _ r = foldStreamShared st yld sng stp $ go (n1 - 1) r
679 -- Somehow "<=" check performs better than a ">"
681 then foldStreamShared st yld sng stp m1
682 else foldStreamShared st yieldk single stp m1
684{-# INLINE dropWhile #-}
685dropWhile :: (a -> Bool) -> Stream m a -> Stream m a
688 go m1 = mkStream $ \st yld sng stp ->
689 let single a | p a = stp
691 yieldk a r | p a = foldStream st yieldk single stp r
692 | otherwise = yld a r
693 in foldStream st yieldk single stp m1
695-------------------------------------------------------------------------------
697-------------------------------------------------------------------------------
699-- Be careful when modifying this, this uses a consM (|:) deliberately to allow
700-- other stream types to overload it.
701{-# INLINE sequence #-}
702sequence :: Monad m => Stream m (m a) -> Stream m a
705 go m1 = mkStream $ \st yld sng stp ->
706 let single ma = ma >>= sng
707 yieldk ma r = foldStreamShared st yld sng stp $ ma `consM` go r
708 in foldStream (adaptState st) yieldk single stp m1
710-------------------------------------------------------------------------------
712-------------------------------------------------------------------------------
714{-# INLINE intersperseM #-}
715intersperseM :: Monad m => m a -> Stream m a -> Stream m a
716intersperseM a = prependingStart
718 prependingStart m1 = mkStream $ \st yld sng stp ->
720 foldStreamShared st yld sng stp $ return i `consM` go x
721 in foldStream st yieldk sng stp m1
722 go m2 = mkStream $ \st yld sng stp ->
723 let single i = foldStreamShared st yld sng stp $ a `consM` fromPure i
726 st yld sng stp $ a `consM` return i `consM` go x
727 in foldStream st yieldk single stp m2
729{-# INLINE intersperse #-}
730intersperse :: Monad m => a -> Stream m a -> Stream m a
731intersperse a = intersperseM (return a)
733{-# INLINE insertBy #-}
734insertBy :: (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
737 go m1 = mkStream $ \st yld _ _ ->
738 let single a = case cmp x a of
739 GT -> yld a (fromPure x)
740 _ -> yld x (fromPure a)
742 yieldk a r = case cmp x a of
744 _ -> yld x (a `cons` r)
745 in foldStream st yieldk single stop m1
747------------------------------------------------------------------------------
749------------------------------------------------------------------------------
751{-# INLINE deleteBy #-}
752deleteBy :: (a -> a -> Bool) -> a -> Stream m a -> Stream m a
755 go m1 = mkStream $ \st yld sng stp ->
756 let single a = if eq x a then stp else sng a
757 yieldk a r = if eq x a
758 then foldStream st yld sng stp r
760 in foldStream st yieldk single stp m1
762-------------------------------------------------------------------------------
764-------------------------------------------------------------------------------
766{-# INLINE mapMaybe #-}
767mapMaybe :: (a -> Maybe b) -> Stream m a -> Stream m b
770 go m1 = mkStream $ \st yld sng stp ->
771 let single a = maybe stp sng (f a)
772 yieldk a r = case f a of
773 Just b -> yld b $ go r
774 Nothing -> foldStream (adaptState st) yieldk single stp r
775 in foldStream (adaptState st) yieldk single stp m1
777------------------------------------------------------------------------------
779------------------------------------------------------------------------------
781-- | Zip two streams serially using a pure zipping function.
784{-# INLINE zipWith #-}
785zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
786zipWith f = zipWithM (\a b -> return (f a b))
788-- | Zip two streams serially using a monadic zipping function.
791{-# INLINE zipWithM #-}
792zipWithM :: Monad m =>
793 (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
798 go mx my = mkStream $ \st yld sng stp -> do
800 let single2 b = f a b >>= sng
801 yield2 b rb = f a b >>= \x -> yld x (go ra rb)
802 in foldStream (adaptState st) yield2 single2 stp my
803 let single1 a = merge a nil
805 foldStream (adaptState st) yield1 single1 stp mx
807------------------------------------------------------------------------------
809------------------------------------------------------------------------------
811{-# INLINE mergeByM #-}
812mergeByM :: Monad m =>
813 (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
818 go mx my = mkStream $ \st yld sng stp -> do
819 let stop = foldStream st yld sng stp my
820 single x = foldStream st yld sng stp (goX0 x my)
821 yield x rx = foldStream st yld sng stp (goX x rx my)
822 foldStream st yield single stop mx
824 goX0 x my = mkStream $ \st yld sng _ -> do
829 GT -> yld y (fromPure x)
830 _ -> yld x (fromPure y)
834 GT -> yld y (goX0 x ry)
835 _ -> yld x (y `cons` ry)
836 in foldStream st yield single stop my
838 goX x mx my = mkStream $ \st yld _ _ -> do
843 GT -> yld y (x `cons` mx)
844 _ -> yld x (goY0 mx y)
848 GT -> yld y (goX x mx ry)
849 _ -> yld x (goY mx y ry)
850 in foldStream st yield single stop my
852 goY0 mx y = mkStream $ \st yld sng _ -> do
857 GT -> yld y (fromPure x)
858 _ -> yld x (fromPure y)
862 GT -> yld y (x `cons` rx)
863 _ -> yld x (goY0 rx y)
864 in foldStream st yield single stop mx
866 goY mx y my = mkStream $ \st yld _ _ -> do
871 GT -> yld y (goX0 x my)
872 _ -> yld x (y `cons` my)
876 GT -> yld y (goX x rx my)
877 _ -> yld x (goY rx y my)
878 in foldStream st yield single stop mx
880{-# INLINE mergeBy #-}
881mergeBy :: (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
882-- XXX GHC: This has slightly worse performance than replacing "r <- cmp x y"
883-- with "let r = cmp x y" in the monadic version. The definition below is
884-- exactly the same as mergeByM except this change.
885-- mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
890 go mx my = mkStream $ \st yld sng stp -> do
891 let stop = foldStream st yld sng stp my
892 single x = foldStream st yld sng stp (goX0 x my)
893 yield x rx = foldStream st yld sng stp (goX x rx my)
894 foldStream st yield single stop mx
896 goX0 x my = mkStream $ \st yld sng _ -> do
900 GT -> yld y (fromPure x)
901 _ -> yld x (fromPure y)
904 GT -> yld y (goX0 x ry)
905 _ -> yld x (y `cons` ry)
906 in foldStream st yield single stop my
908 goX x mx my = mkStream $ \st yld _ _ -> do
912 GT -> yld y (x `cons` mx)
913 _ -> yld x (goY0 mx y)
916 GT -> yld y (goX x mx ry)
917 _ -> yld x (goY mx y ry)
918 in foldStream st yield single stop my
920 goY0 mx y = mkStream $ \st yld sng _ -> do
924 GT -> yld y (fromPure x)
925 _ -> yld x (fromPure y)
928 GT -> yld y (x `cons` rx)
929 _ -> yld x (goY0 rx y)
930 in foldStream st yield single stop mx
932 goY mx y my = mkStream $ \st yld _ _ -> do
936 GT -> yld y (goX0 x my)
937 _ -> yld x (y `cons` my)
940 GT -> yld y (goX x rx my)
941 _ -> yld x (goY rx y my)
942 in foldStream st yield single stop mx
944------------------------------------------------------------------------------
945-- Transformation comprehensions
946------------------------------------------------------------------------------
949the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
953 Nothing -> return Nothing
954 Just (h, t) -> go h t
957 let single a | h == a = return $ Just h
958 | otherwise = return Nothing
959 yieldk a r | h == a = go h r
960 | otherwise = return Nothing
961 in foldStream defState yieldk single (return $ Just h) m1
963------------------------------------------------------------------------------
964-- Alternative & MonadPlus
965------------------------------------------------------------------------------
967_alt :: Stream m a -> Stream m a -> Stream m a
968_alt m1 m2 = mkStream $ \st yld sng stp ->
969 let stop = foldStream st yld sng stp m2
970 in foldStream st yld sng stop m1
972------------------------------------------------------------------------------
974------------------------------------------------------------------------------
977-- XXX handle and test cross thread state transfer
980 => Stream m a -> (e -> Stream m a) -> Stream m a
982 mkStream $ \_ stp sng yld ->
983 let run x = unStream x Nothing stp sng yieldk
984 handle r = r `catchError` \e -> run $ h e
985 yieldk a r = yld a (withCatchError r h)
989-------------------------------------------------------------------------------
991-------------------------------------------------------------------------------
993-- Inlined definition.
994{-# INLINE splitAt #-}
995splitAt :: Int -> [a] -> ([a],[a])
998 | otherwise = splitAt' n ls
1000 splitAt' :: Int -> [a] -> ([a], [a])
1001 splitAt' _ [] = ([], [])
1002 splitAt' 1 (x:xs) = ([x], xs)
1003 splitAt' m (x:xs) = (x:xs', xs'')
1005 (xs', xs'') = splitAt' (m - 1) xs
1007-- | Run a 'Parser' over a stream and return rest of the Stream.
1008{-# INLINE_NORMAL parseBreak #-}
1013 -> m (b, Stream m a)
1014parseBreak (PR.Parser pstep initial extract) stream = do
1017 PR.IPartial s -> goStream stream [] s
1018 PR.IDone b -> return (b, stream)
1019 PR.IError err -> throwM $ PR.ParseError err
1023 -- "buf" contains last few items in the stream that we may have to
1026 -- XXX currently we are using a dumb list based approach for backtracking
1027 -- buffer. This can be replaced by a sliding/ring buffer using Data.Array.
1028 -- That will allow us more efficient random back and forth movement.
1029 goStream st buf !pst =
1033 PR.Error err -> throwM $ PR.ParseError err
1035 assertM(n <= length buf)
1036 let src0 = Prelude.take n buf
1037 src = Prelude.reverse src0
1038 return (b, fromList src)
1039 PR.Partial _ _ -> error "Bug: parseBreak: Partial in extract"
1040 PR.Continue 0 _ -> error "parseBreak: extract, Continue 0 creates infinite loop"
1041 PR.Continue n s -> do
1042 assertM(n <= length buf)
1043 let (src0, buf1) = splitAt n buf
1044 src = Prelude.reverse src0
1045 goBuf nil buf1 src s
1046 single x = yieldk x nil
1050 PR.Partial 0 s -> goStream r [] s
1051 PR.Partial n s -> do
1052 assertM(n <= length (x:buf))
1053 let src0 = Prelude.take n (x:buf)
1054 src = Prelude.reverse src0
1056 PR.Continue 0 s -> goStream r (x:buf) s
1057 PR.Continue n s -> do
1058 assertM(n <= length (x:buf))
1059 let (src0, buf1) = splitAt n (x:buf)
1060 src = Prelude.reverse src0
1062 PR.Done 0 b -> return (b, r)
1064 assertM(n <= length (x:buf))
1065 let src0 = Prelude.take n (x:buf)
1066 src = Prelude.reverse src0
1067 return (b, serial (fromList src) r)
1068 PR.Error err -> throwM $ PR.ParseError err
1069 in foldStream defState yieldk single stop st
1071 goBuf st buf [] !pst = goStream st buf pst
1072 goBuf st buf (x:xs) !pst = do
1075 PR.Partial 0 s -> goBuf st [] xs s
1076 PR.Partial n s -> do
1077 assert (n <= length (x:buf)) (return ())
1078 let src0 = Prelude.take n (x:buf)
1079 src = Prelude.reverse src0 ++ xs
1081 PR.Continue 0 s -> goBuf st (x:buf) xs s
1082 PR.Continue n s -> do
1083 assert (n <= length (x:buf)) (return ())
1084 let (src0, buf1) = splitAt n (x:buf)
1085 src = Prelude.reverse src0 ++ xs
1088 assert (n <= length (x:buf)) (return ())
1089 let src0 = Prelude.take n (x:buf)
1090 src = Prelude.reverse src0
1091 return (b, serial (fromList src) st)
1092 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