1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE ExistentialQuantification #-}
5{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE RankNTypes #-}
13-- Module : Streamly.Streams.StreamD
14-- Copyright : (c) 2018 Harendra Kumar
17-- Maintainer : harendra.kumar@gmail.com
18-- Stability : experimental
21-- Direct style re-implementation of CPS style stream in StreamK module. The
22-- symbol or suffix 'D' in this module denotes the "Direct" style. GHC is able
23-- to INLINE and fuse direct style better, providing better performance than
27-- import qualified Streamly.Streams.StreamD as D
30-- Some of functions in this file have been adapted from the vector
31-- library, https://hackage.haskell.org/package/vector.
33module Streamly.Streams.StreamD
51 -- ** Specialized Generation
52 -- | Generate a monadic stream from a seed.
57 -- | Transform an input structure into a stream.
58 -- | Direct style stream does not support @fromFoldable@.
74 -- ** Specialized Folds
102 -- | Transform a stream into another type.
108 -- ** By folding (scans)
154 -- * Transformation comprehensions
159import Data.Maybe (fromJust, isJust)
160import GHC.Types ( SPEC(..) )
162 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
163 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
164 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
167import Streamly.SVar (MonadAsync, State(..), defState, rstState)
169import qualified Streamly.Streams.StreamK as K
171------------------------------------------------------------------------------
172-- The direct style stream type
173------------------------------------------------------------------------------
175-- | A stream is a succession of 'Step's. A 'Yield' produces a single value and
176-- the next state of the stream. 'Stop' indicates there are no more values in
178data Step s a = Yield a s | Skip s | Stop
180instance Functor (Step s) where
182 fmap f (Yield x s) = Yield (f x) s
183 fmap _ (Skip s) = Skip s
187-- | A stream consists of a step function that generates the next step given a
188-- current state, and the current state.
189data Stream m a = forall s. Stream (State K.Stream m a -> s -> m (Step s a)) s
191------------------------------------------------------------------------------
193------------------------------------------------------------------------------
195-- | An empty 'Stream'.
196{-# INLINE_NORMAL nil #-}
197nil :: Monad m => Stream m a
198nil = Stream (\_ _ -> return Stop) ()
200-- | Can fuse but has O(n^2) complexity.
201{-# INLINE_NORMAL cons #-}
202cons :: Monad m => a -> Stream m a -> Stream m a
203cons x (Stream step state) = Stream step1 Nothing
205 {-# INLINE_LATE step1 #-}
206 step1 _ Nothing = return $ Yield x (Just state)
207 step1 gst (Just st) = do
208 r <- step (rstState gst) st
211 Yield a s -> Yield a (Just s)
212 Skip s -> Skip (Just s)
215-------------------------------------------------------------------------------
217-------------------------------------------------------------------------------
219-- Does not fuse, has the same performance as the StreamK version.
220{-# INLINE_NORMAL uncons #-}
221uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
222uncons (Stream step state) = go state
225 r <- step defState st
227 Yield x s -> return $ Just (x, Stream step s)
229 Stop -> return Nothing
231------------------------------------------------------------------------------
232-- Generation by unfold
233------------------------------------------------------------------------------
235{-# INLINE_NORMAL unfoldrM #-}
236unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
237unfoldrM next state = Stream step state
239 {-# INLINE_LATE step #-}
243 Just (x, s) -> Yield x s
246{-# INLINE_LATE unfoldr #-}
247unfoldr :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a
248unfoldr f = unfoldrM (return . f)
250------------------------------------------------------------------------------
251-- Specialized Generation
252------------------------------------------------------------------------------
254repeat :: Monad m => a -> Stream m a
255repeat x = Stream (\_ _ -> return $ Yield x ()) ()
257{-# INLINE_NORMAL enumFromStepN #-}
258enumFromStepN :: (Num a, Monad m) => a -> a -> Int -> Stream m a
259enumFromStepN from stride n =
260 from `seq` stride `seq` n `seq` Stream step (from, n)
262 {-# INLINE_LATE step #-}
263 step _ (x, i) | i > 0 = return $ Yield x (x + stride, i - 1)
264 | otherwise = return Stop
266-------------------------------------------------------------------------------
267-- Generation by Conversion
268-------------------------------------------------------------------------------
270-- | Create a singleton 'Stream' from a pure value.
271{-# INLINE_NORMAL yield #-}
272yield :: Monad m => a -> Stream m a
273yield x = Stream (\_ s -> return $ step undefined s) True
275 {-# INLINE_LATE step #-}
276 step _ True = Yield x False
279-- | Create a singleton 'Stream' from a monadic action.
280{-# INLINE_NORMAL yieldM #-}
281yieldM :: Monad m => m a -> Stream m a
282yieldM m = Stream step True
284 {-# INLINE_LATE step #-}
285 step _ True = m >>= \x -> return $ Yield x False
286 step _ False = return Stop
288-- XXX we need the MonadAsync constraint because of a rewrite rule.
289-- | Convert a list of monadic actions to a 'Stream'
290{-# INLINE_LATE fromListM #-}
291fromListM :: MonadAsync m => [m a] -> Stream m a
292fromListM = Stream step
294 {-# INLINE_LATE step #-}
295 step _ (m:ms) = m >>= \x -> return $ Yield x ms
296 step _ [] = return Stop
298-- | Convert a list of pure values to a 'Stream'
299{-# INLINE_LATE fromList #-}
300fromList :: Monad m => [a] -> Stream m a
301fromList = Stream step
303 {-# INLINE_LATE step #-}
304 step _ (x:xs) = return $ Yield x xs
305 step _ [] = return Stop
307-- XXX pass the state to streamD
308{-# INLINE_LATE fromStreamK #-}
309fromStreamK :: Monad m => K.Stream m a -> Stream m a
310fromStreamK = Stream step
313 let stop = return Stop
314 single a = return $ Yield a K.nil
315 yieldk a r = return $ Yield a r
316 in K.unStream m1 gst stop single yieldk
318{-# INLINE toStreamD #-}
319toStreamD :: (K.IsStream t, Monad m) => t m a -> Stream m a
320toStreamD = fromStreamK . K.toStream
322------------------------------------------------------------------------------
323-- Elimination by Folds
324------------------------------------------------------------------------------
326{-# INLINE_NORMAL foldrM #-}
327foldrM :: Monad m => (a -> b -> m b) -> b -> Stream m a -> m b
328foldrM f z (Stream step state) = go SPEC state
331 r <- step defState st
333 Yield x s -> go SPEC s >>= f x
337{-# INLINE_NORMAL foldr #-}
338foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b
339foldr f = foldrM (\a b -> return (f a b))
341{-# INLINE_NORMAL foldr1 #-}
342foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
346 Nothing -> return Nothing
347 Just (h, t) -> fmap Just (foldr f h t)
349{-# INLINE_NORMAL foldlM' #-}
350foldlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> m b
351foldlM' fstep begin (Stream step state) = go SPEC begin state
353 go !_ acc st = acc `seq` do
354 r <- step defState st
359 Skip s -> go SPEC acc s
363foldl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> m b
364foldl' fstep = foldlM' (\b a -> return (fstep b a))
366------------------------------------------------------------------------------
368------------------------------------------------------------------------------
370-- | Run a streaming composition, discard the results.
371{-# INLINE_LATE runStream #-}
372runStream :: Monad m => Stream m a -> m ()
373runStream (Stream step state) = go SPEC state
376 r <- step defState st
378 Yield _ s -> go SPEC s
382{-# INLINE_NORMAL null #-}
383null :: Monad m => Stream m a -> m Bool
384null (Stream step state) = go state
387 r <- step defState st
389 Yield _ _ -> return False
394{-# INLINE_NORMAL head #-}
395head :: Monad m => Stream m a -> m (Maybe a)
396head (Stream step state) = go state
399 r <- step defState st
401 Yield x _ -> return (Just x)
403 Stop -> return Nothing
405-- Does not fuse, has the same performance as the StreamK version.
406{-# INLINE_NORMAL tail #-}
407tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
408tail (Stream step state) = go state
411 r <- step defState st
413 Yield _ s -> return (Just $ Stream step s)
415 Stop -> return Nothing
417-- XXX will it fuse? need custom impl?
418{-# INLINE_NORMAL last #-}
419last :: Monad m => Stream m a -> m (Maybe a)
420last = foldl' (\_ y -> Just y) Nothing
422{-# INLINE_NORMAL elem #-}
423elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
424elem e (Stream step state) = go state
427 r <- step defState st
430 | x == e -> return True
435{-# INLINE_NORMAL notElem #-}
436notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
437notElem e s = fmap not (elem e s)
439{-# INLINE_NORMAL all #-}
440all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
441all p (Stream step state) = go state
444 r <- step defState st
448 | otherwise -> return False
452{-# INLINE_NORMAL any #-}
453any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
454any p (Stream step state) = go state
457 r <- step defState st
465{-# INLINE_NORMAL maximum #-}
466maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
467maximum (Stream step state) = go Nothing state
470 r <- step defState st
472 Yield x s -> go (Just x) s
473 Skip s -> go Nothing s
474 Stop -> return Nothing
475 go (Just acc) st = do
476 r <- step defState st
479 | acc <= x -> go (Just x) s
480 | otherwise -> go (Just acc) s
481 Skip s -> go (Just acc) s
482 Stop -> return (Just acc)
484{-# INLINE_NORMAL maximumBy #-}
485maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
486maximumBy cmp (Stream step state) = go Nothing state
489 r <- step defState st
491 Yield x s -> go (Just x) s
492 Skip s -> go Nothing s
493 Stop -> return Nothing
494 go (Just acc) st = do
495 r <- step defState st
497 Yield x s -> case cmp acc x of
498 GT -> go (Just acc) s
500 Skip s -> go (Just acc) s
501 Stop -> return (Just acc)
503{-# INLINE_NORMAL minimum #-}
504minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
505minimum (Stream step state) = go Nothing state
508 r <- step defState st
510 Yield x s -> go (Just x) s
511 Skip s -> go Nothing s
512 Stop -> return Nothing
513 go (Just acc) st = do
514 r <- step defState st
517 | acc <= x -> go (Just acc) s
518 | otherwise -> go (Just x) s
519 Skip s -> go (Just acc) s
520 Stop -> return (Just acc)
522{-# INLINE_NORMAL minimumBy #-}
523minimumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
524minimumBy cmp (Stream step state) = go Nothing state
527 r <- step defState st
529 Yield x s -> go (Just x) s
530 Skip s -> go Nothing s
531 Stop -> return Nothing
532 go (Just acc) st = do
533 r <- step defState st
535 Yield x s -> case cmp acc x of
538 Skip s -> go (Just acc) s
539 Stop -> return (Just acc)
541{-# INLINE_NORMAL (!!) #-}
542(!!) :: (Monad m) => Stream m a -> Int -> m (Maybe a)
543(Stream step state) !! i = go i state
546 r <- step defState st
548 Yield x s | n < 0 -> return Nothing
549 | n == 0 -> return $ Just x
550 | otherwise -> go (n - 1) s
552 Stop -> return Nothing
554{-# INLINE_NORMAL lookup #-}
555lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
556lookup e (Stream step state) = go state
559 r <- step defState st
561 Yield (a, b) s -> if e == a then return (Just b) else go s
563 Stop -> return Nothing
565{-# INLINE_NORMAL find #-}
566find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
567find p (Stream step state) = go state
570 r <- step defState st
572 Yield x s -> if p x then return (Just x) else go s
574 Stop -> return Nothing
576{-# INLINE_NORMAL findIndices #-}
577findIndices :: Monad m => (a -> Bool) -> Stream m a -> Stream m Int
578findIndices p (Stream step state) = Stream step' (state, 0)
580 {-# INLINE_LATE step' #-}
581 step' gst (st, i) = do
582 r <- step (rstState gst) st
584 Yield x s -> if p x then Yield i (s, i+1) else Skip (s, i+1)
585 Skip s -> Skip (s, i+1)
588------------------------------------------------------------------------------
590------------------------------------------------------------------------------
592{-# INLINE_NORMAL isPrefixOf #-}
593isPrefixOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
594isPrefixOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
596 go (sa, sb, Nothing) = do
597 r <- stepa defState sa
599 Yield x sa' -> go (sa', sb, Just x)
600 Skip sa' -> go (sa', sb, Nothing)
603 go (sa, sb, Just x) = do
604 r <- stepb defState sb
608 then go (sa, sb', Nothing)
610 Skip sb' -> go (sa, sb', Just x)
613{-# INLINE_NORMAL isSubsequenceOf #-}
614isSubsequenceOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
615isSubsequenceOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
617 go (sa, sb, Nothing) = do
618 r <- stepa defState sa
620 Yield x sa' -> go (sa', sb, Just x)
621 Skip sa' -> go (sa', sb, Nothing)
624 go (sa, sb, Just x) = do
625 r <- stepb defState sb
629 then go (sa, sb', Nothing)
630 else go (sa, sb', Just x)
631 Skip sb' -> go (sa, sb', Just x)
634{-# INLINE_NORMAL stripPrefix #-}
635stripPrefix :: (Eq a, Monad m) => Stream m a -> Stream m a -> m (Maybe (Stream m a))
636stripPrefix (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
638 go (sa, sb, Nothing) = do
639 r <- stepa defState sa
641 Yield x sa' -> go (sa', sb, Just x)
642 Skip sa' -> go (sa', sb, Nothing)
643 Stop -> return $ Just (Stream stepb sb)
645 go (sa, sb, Just x) = do
646 r <- stepb defState sb
650 then go (sa, sb', Nothing)
652 Skip sb' -> go (sa, sb', Just x)
653 Stop -> return Nothing
655------------------------------------------------------------------------------
657------------------------------------------------------------------------------
659-- | Execute a monadic action for each element of the 'Stream'
660{-# INLINE_NORMAL mapM_ #-}
661mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
662mapM_ m = runStream . mapM m
664------------------------------------------------------------------------------
666------------------------------------------------------------------------------
669toList :: Monad m => Stream m a -> m [a]
672-- Convert a direct stream to and from CPS encoded stream
673{-# INLINE_LATE toStreamK #-}
674toStreamK :: Monad m => Stream m a -> K.Stream m a
675toStreamK (Stream step state) = go state
677 go st = K.Stream $ \gst stp sng yld -> do
680 Yield x s -> yld x (go s)
681 Skip s -> K.unStream (go s) gst stp sng yld
684#ifndef DISABLE_FUSION
685{-# RULES "fromStreamK/toStreamK fusion"
686 forall s. toStreamK (fromStreamK s) = s #-}
687{-# RULES "toStreamK/fromStreamK fusion"
688 forall s. fromStreamK (toStreamK s) = s #-}
691{-# INLINE fromStreamD #-}
692fromStreamD :: (K.IsStream t, Monad m) => Stream m a -> t m a
693fromStreamD = K.fromStream . toStreamK
695------------------------------------------------------------------------------
696-- Transformation by Folding (Scans)
697------------------------------------------------------------------------------
699{-# INLINE_NORMAL postscanlM' #-}
700postscanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
701postscanlM' fstep begin (Stream step state) =
702 begin `seq` Stream step' (state, begin)
704 {-# INLINE_LATE step' #-}
705 step' gst (st, acc) = acc `seq` do
706 r <- step (rstState gst) st
710 y `seq` return (Yield y (s, y))
711 Skip s -> return $ Skip (s, acc)
714{-# INLINE_NORMAL postscanlM #-}
715postscanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
716postscanlM fstep begin (Stream step state) = Stream step' (state, begin)
718 {-# INLINE_LATE step' #-}
719 step' gst (st, acc) = do
720 r <- step (rstState gst) st
724 return (Yield y (s, y))
725 Skip s -> return $ Skip (s, acc)
728{-# INLINE_NORMAL scanlM' #-}
729scanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
730scanlM' fstep begin s = begin `seq` (begin `cons` postscanlM' fstep begin s)
733scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
734scanl' f = scanlM' (\a b -> return (f a b))
736{-# INLINE_NORMAL scanlM #-}
737scanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
738scanlM fstep begin s = begin `cons` postscanlM fstep begin s
741scanl :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
742scanl f = scanlM (\a b -> return (f a b))
744{-# INLINE_NORMAL scanl1M #-}
745scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
746scanl1M fstep (Stream step state) = Stream step' (state, Nothing)
748 {-# INLINE_LATE step' #-}
749 step' gst (st, Nothing) = do
750 r <- step (rstState gst) st
752 Yield x s -> return $ Yield x (s, Just x)
753 Skip s -> return $ Skip (s, Nothing)
756 step' gst (st, Just acc) = do
757 r <- step (rstState gst) st
761 return $ Yield z (s, Just z)
762 Skip s -> return $ Skip (s, Just acc)
766scanl1 :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
767scanl1 f = scanl1M (\x y -> return (f x y))
769{-# INLINE_NORMAL scanl1M' #-}
770scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
771scanl1M' fstep (Stream step state) = Stream step' (state, Nothing)
773 {-# INLINE_LATE step' #-}
774 step' gst (st, Nothing) = do
775 r <- step (rstState gst) st
777 Yield x s -> x `seq` return $ Yield x (s, Just x)
778 Skip s -> return $ Skip (s, Nothing)
781 step' gst (st, Just acc) = acc `seq` do
782 r <- step (rstState gst) st
786 z `seq` return $ Yield z (s, Just z)
787 Skip s -> return $ Skip (s, Just acc)
790{-# INLINE scanl1' #-}
791scanl1' :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
792scanl1' f = scanl1M' (\x y -> return (f x y))
794-------------------------------------------------------------------------------
796-------------------------------------------------------------------------------
798{-# INLINE_NORMAL take #-}
799take :: Monad m => Int -> Stream m a -> Stream m a
800take n (Stream step state) = n `seq` Stream step' (state, 0)
802 {-# INLINE_LATE step' #-}
803 step' gst (st, i) | i < n = do
804 r <- step (rstState gst) st
806 Yield x s -> Yield x (s, i + 1)
807 Skip s -> Skip (s, i)
809 step' _ (_, _) = return Stop
811{-# INLINE_NORMAL takeWhileM #-}
812takeWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
813takeWhileM f (Stream step state) = Stream step' state
815 {-# INLINE_LATE step' #-}
817 r <- step (rstState gst) st
821 return $ if b then Yield x s else Stop
822 Skip s -> return $ Skip s
825{-# INLINE takeWhile #-}
826takeWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
827takeWhile f = takeWhileM (return . f)
829{-# INLINE_NORMAL drop #-}
830drop :: Monad m => Int -> Stream m a -> Stream m a
831drop n (Stream step state) = Stream step' (state, Just n)
833 {-# INLINE_LATE step' #-}
834 step' gst (st, Just i)
836 r <- step (rstState gst) st
839 Yield _ s -> Skip (s, Just (i - 1))
840 Skip s -> Skip (s, Just i)
842 | otherwise = return $ Skip (st, Nothing)
844 step' gst (st, Nothing) = do
845 r <- step (rstState gst) st
848 Yield x s -> Yield x (s, Nothing)
849 Skip s -> Skip (s, Nothing)
852data DropWhileState s a
857{-# INLINE_NORMAL dropWhileM #-}
858dropWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
859dropWhileM f (Stream step state) = Stream step' (DropWhileDrop state)
861 {-# INLINE_LATE step' #-}
862 step' gst (DropWhileDrop st) = do
863 r <- step (rstState gst) st
868 then return $ Skip (DropWhileDrop s)
869 else return $ Skip (DropWhileYield x s)
870 Skip s -> return $ Skip (DropWhileDrop s)
873 step' gst (DropWhileNext st) = do
874 r <- step (rstState gst) st
876 Yield x s -> return $ Skip (DropWhileYield x s)
877 Skip s -> return $ Skip (DropWhileNext s)
880 step' _ (DropWhileYield x st) = return $ Yield x (DropWhileNext st)
882{-# INLINE dropWhile #-}
883dropWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
884dropWhile f = dropWhileM (return . f)
886{-# INLINE_NORMAL filterM #-}
887filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
888filterM f (Stream step state) = Stream step' state
890 {-# INLINE_LATE step' #-}
892 r <- step (rstState gst) st
899 Skip s -> return $ Skip s
903filter :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
904filter f = filterM (return . f)
906------------------------------------------------------------------------------
907-- Transformation by Mapping
908------------------------------------------------------------------------------
910-- | Map a monadic function over a 'Stream'
911{-# INLINE_NORMAL mapM #-}
912mapM :: Monad m => (a -> m b) -> Stream m a -> Stream m b
913mapM f (Stream step state) = Stream step' state
915 {-# INLINE_LATE step' #-}
917 r <- step (rstState gst) st
919 Yield x s -> f x >>= \a -> return $ Yield a s
920 Skip s -> return $ Skip s
924map :: Monad m => (a -> b) -> Stream m a -> Stream m b
925map f = mapM (return . f)
927{-# INLINE_NORMAL sequence #-}
928sequence :: Monad m => Stream m (m a) -> Stream m a
929sequence (Stream step state) = Stream step' state
931 {-# INLINE_LATE step' #-}
933 r <- step (rstState gst) st
935 Yield x s -> x >>= \a -> return (Yield a s)
936 Skip s -> return $ Skip s
939------------------------------------------------------------------------------
941------------------------------------------------------------------------------
943{-# INLINE_NORMAL insertBy #-}
944insertBy :: Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
945insertBy cmp a (Stream step state) = Stream step' (state, False, Nothing)
947 {-# INLINE_LATE step' #-}
948 step' gst (st, False, _) = do
949 r <- step (rstState gst) st
951 Yield x s -> case cmp a x of
952 GT -> return $ Yield x (s, False, Nothing)
953 _ -> return $ Yield a (s, True, Just x)
954 Skip s -> return $ Skip (s, False, Nothing)
955 Stop -> return $ Yield a (st, True, Nothing)
957 step' _ (_, True, Nothing) = return Stop
959 step' gst (st, True, Just prev) = do
960 r <- step (rstState gst) st
962 Yield x s -> return $ Yield prev (s, True, Just x)
963 Skip s -> return $ Skip (s, True, Just prev)
964 Stop -> return $ Yield prev (st, True, Nothing)
966------------------------------------------------------------------------------
968------------------------------------------------------------------------------
970{-# INLINE_NORMAL deleteBy #-}
971deleteBy :: Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a
972deleteBy eq x (Stream step state) = Stream step' (state, False)
974 {-# INLINE_LATE step' #-}
975 step' gst (st, False) = do
976 r <- step (rstState gst) st
978 Yield y s -> return $
979 if eq x y then Skip (s, True) else Yield y (s, False)
980 Skip s -> return $ Skip (s, False)
983 step' gst (st, True) = do
984 r <- step (rstState gst) st
986 Yield y s -> return $ Yield y (s, True)
987 Skip s -> return $ Skip (s, True)
990------------------------------------------------------------------------------
991-- Transformation by Map and Filter
992------------------------------------------------------------------------------
994-- XXX Will this always fuse properly?
995{-# INLINE_NORMAL mapMaybe #-}
996mapMaybe :: Monad m => (a -> Maybe b) -> Stream m a -> Stream m b
997mapMaybe f = fmap fromJust . filter isJust . map f
999{-# INLINE_NORMAL mapMaybeM #-}
1000mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b
1001mapMaybeM f = fmap fromJust . filter isJust . mapM f
1003------------------------------------------------------------------------------
1005------------------------------------------------------------------------------
1007{-# INLINE_NORMAL zipWithM #-}
1009 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
1010zipWithM f (Stream stepa ta) (Stream stepb tb) = Stream step (ta, tb, Nothing)
1012 {-# INLINE_LATE step #-}
1013 step gst (sa, sb, Nothing) = do
1014 r <- stepa (rstState gst) sa
1017 Yield x sa' -> Skip (sa', sb, Just x)
1018 Skip sa' -> Skip (sa', sb, Nothing)
1021 step gst (sa, sb, Just x) = do
1022 r <- stepb (rstState gst) sb
1026 return $ Yield z (sa, sb', Nothing)
1027 Skip sb' -> return $ Skip (sa, sb', Just x)
1030{-# RULES "zipWithM xs xs"
1031 forall f xs. zipWithM f xs xs = mapM (\x -> f x x) xs #-}
1033{-# INLINE zipWith #-}
1034zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
1035zipWith f = zipWithM (\a b -> return (f a b))
1037------------------------------------------------------------------------------
1039------------------------------------------------------------------------------
1041{-# INLINE_NORMAL eqBy #-}
1042eqBy :: Monad m => (a -> b -> Bool) -> Stream m a -> Stream m b -> m Bool
1043eqBy eq (Stream step1 t1) (Stream step2 t2) = eq_loop0 SPEC t1 t2
1045 eq_loop0 !_ s1 s2 = do
1046 r <- step1 defState s1
1048 Yield x s1' -> eq_loop1 SPEC x s1' s2
1049 Skip s1' -> eq_loop0 SPEC s1' s2
1052 eq_loop1 !_ x s1 s2 = do
1053 r <- step2 defState s2
1056 | eq x y -> eq_loop0 SPEC s1 s2'
1057 | otherwise -> return False
1058 Skip s2' -> eq_loop1 SPEC x s1 s2'
1059 Stop -> return False
1062 r <- step2 defState s2
1064 Yield _ _ -> return False
1065 Skip s2' -> eq_null s2'
1068-- | Compare two streams lexicographically
1069{-# INLINE_NORMAL cmpBy #-}
1072 => (a -> b -> Ordering) -> Stream m a -> Stream m b -> m Ordering
1073cmpBy cmp (Stream step1 t1) (Stream step2 t2) = cmp_loop0 SPEC t1 t2
1075 cmp_loop0 !_ s1 s2 = do
1076 r <- step1 defState s1
1078 Yield x s1' -> cmp_loop1 SPEC x s1' s2
1079 Skip s1' -> cmp_loop0 SPEC s1' s2
1082 cmp_loop1 !_ x s1 s2 = do
1083 r <- step2 defState s2
1085 Yield y s2' -> case x `cmp` y of
1086 EQ -> cmp_loop0 SPEC s1 s2'
1088 Skip s2' -> cmp_loop1 SPEC x s1 s2'
1092 r <- step2 defState s2
1094 Yield _ _ -> return LT
1095 Skip s2' -> cmp_null s2'
1098------------------------------------------------------------------------------
1100------------------------------------------------------------------------------
1102{-# INLINE_NORMAL mergeBy #-}
1103mergeBy :: (Monad m) => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
1104mergeBy f (Stream stepa ta) (Stream stepb tb) =
1105 Stream step (Just ta, Just tb, Nothing, Nothing)
1107 {-# INLINE_LATE step #-}
1109 -- one of the values is missing, and the corresponding stream is running
1110 step gst (Just sa, sb, Nothing, b) = do
1111 r <- stepa (rstState gst) sa
1113 Yield a sa' -> Skip (Just sa', sb, Just a, b)
1114 Skip sa' -> Skip (Just sa', sb, Nothing, b)
1115 Stop -> Skip (Nothing, sb, Nothing, b)
1117 step gst (sa, Just sb, a, Nothing) = do
1118 r <- stepb (rstState gst) sb
1120 Yield b sb' -> Skip (sa, Just sb', a, Just b)
1121 Skip sb' -> Skip (sa, Just sb', a, Nothing)
1122 Stop -> Skip (sa, Nothing, a, Nothing)
1124 -- both the values are available
1125 step _ (sa, sb, Just a, Just b) =
1126 return $ case f a b of
1127 LT -> Yield a (sa, sb, Nothing, Just b)
1128 _ -> Yield b (sa, sb, Just a, Nothing)
1130 -- one of the values is missing, corresponding stream is done
1131 step _ (Nothing, sb, Nothing, Just b) = do
1132 return $ Yield b (Nothing, sb, Nothing, Nothing)
1134 step _ (sa, Nothing, Just a, Nothing) = do
1135 return $ Yield a (sa, Nothing, Nothing, Nothing)
1137 step _ (Nothing, Nothing, Nothing, Nothing) = return Stop
1139------------------------------------------------------------------------------
1140-- Transformation comprehensions
1141------------------------------------------------------------------------------
1143{-# INLINE_NORMAL the #-}
1144the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
1145the (Stream step state) = go state
1148 r <- step defState st
1150 Yield x s -> go' x s
1152 Stop -> return Nothing
1154 r <- step defState st
1156 Yield x s | x == n -> go' n s
1157 | otherwise -> return Nothing
1159 Stop -> return (Just n)
1161------------------------------------------------------------------------------
1163------------------------------------------------------------------------------
1165instance Monad m => Functor (Stream m) where
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