1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE ExistentialQuantification #-}
5{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE PatternSynonyms #-}
9{-# LANGUAGE ViewPatterns #-}
10{-# LANGUAGE RankNTypes #-}
15-- Module : Streamly.Streams.StreamD
16-- Copyright : (c) 2018 Harendra Kumar
17-- Copyright : (c) Roman Leshchinskiy 2008-2010
20-- Maintainer : harendra.kumar@gmail.com
21-- Stability : experimental
24-- Direct style re-implementation of CPS style stream in StreamK module. The
25-- symbol or suffix 'D' in this module denotes the "Direct" style. GHC is able
26-- to INLINE and fuse direct style better, providing better performance than
30-- import qualified Streamly.Streams.StreamD as D
33-- Some of the functions in this file have been adapted from the vector
34-- library, https://hackage.haskell.org/package/vector.
36module Streamly.Streams.StreamD
54 -- ** Specialized Generation
55 -- | Generate a monadic stream from a seed.
78 -- | Transform an input structure into a stream.
79 -- | Direct style stream does not support @fromFoldable@.
95 -- ** Specialized Folds
126 -- | Transform a stream into another type.
132 -- ** By folding (scans)
189 -- * Transformation comprehensions
194import Data.Maybe (fromJust, isJust)
195import GHC.Types ( SPEC(..) )
197 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
198 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
199 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
200 (!!), scanl, scanl1, concatMap, replicate, enumFromTo)
202import Streamly.SVar (MonadAsync, defState, adaptState)
204import Streamly.Streams.StreamD.Type
205import qualified Streamly.Streams.StreamK as K
207------------------------------------------------------------------------------
209------------------------------------------------------------------------------
211-- | An empty 'Stream'.
212{-# INLINE_NORMAL nil #-}
213nil :: Monad m => Stream m a
214nil = Stream (\_ _ -> return Stop) ()
216-- | Can fuse but has O(n^2) complexity.
217{-# INLINE_NORMAL cons #-}
218cons :: Monad m => a -> Stream m a -> Stream m a
219cons x (Stream step state) = Stream step1 Nothing
221 {-# INLINE_LATE step1 #-}
222 step1 _ Nothing = return $ Yield x (Just state)
223 step1 gst (Just st) = do
227 Yield a s -> Yield a (Just s)
228 Skip s -> Skip (Just s)
231-------------------------------------------------------------------------------
233-------------------------------------------------------------------------------
235-- Does not fuse, has the same performance as the StreamK version.
236{-# INLINE_NORMAL uncons #-}
237uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
238uncons (UnStream step state) = go state
241 r <- step defState st
243 Yield x s -> return $ Just (x, Stream step s)
245 Stop -> return Nothing
247------------------------------------------------------------------------------
248-- Generation by unfold
249------------------------------------------------------------------------------
251{-# INLINE_NORMAL unfoldrM #-}
252unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
253unfoldrM next state = Stream step state
255 {-# INLINE_LATE step #-}
259 Just (x, s) -> Yield x s
262{-# INLINE_LATE unfoldr #-}
263unfoldr :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a
264unfoldr f = unfoldrM (return . f)
266------------------------------------------------------------------------------
267-- Specialized Generation
268------------------------------------------------------------------------------
270repeat :: Monad m => a -> Stream m a
271repeat x = Stream (\_ _ -> return $ Yield x ()) ()
273{-# INLINE_NORMAL replicateM #-}
274replicateM :: Monad m => Int -> m a -> Stream m a
275replicateM n p = Stream step n
277 {-# INLINE_LATE step #-}
278 step _ i | i <= 0 = return Stop
281 return $ Yield x (i - 1)
283{-# INLINE_NORMAL replicate #-}
284replicate :: Monad m => Int -> a -> Stream m a
285replicate n x = replicateM n (return x)
287-- This would not work properly for floats, therefore we put an Integral
289-- | Can be used to enumerate unbounded integrals. This does not check for
290-- overflow or underflow for bounded integrals.
291{-# INLINE_NORMAL intFromStep #-}
292intFromStep :: (Integral a, Monad m) => a -> a -> Stream m a
293intFromStep from stride =
294 from `seq` stride `seq` Stream step from
296 {-# INLINE_LATE step #-}
297 step _ !x = return $ Yield x $! (x + stride)
299-- We are assuming that "to" is constrained by the type to be within
301{-# INLINE intFromTo #-}
302intFromTo :: (Monad m, Integral a) => a -> a -> Stream m a
303intFromTo from to = takeWhile (<= to) $ intFromStep from 1
305{-# INLINE intFrom #-}
306intFrom :: (Monad m, Integral a, Bounded a) => a -> Stream m a
307intFrom from = intFromTo from maxBound
309data EnumState a = EnumInit | EnumYield a a a | EnumStop
311{-# INLINE_NORMAL intFromThenToUp #-}
312intFromThenToUp :: (Monad m, Integral a) => a -> a -> a -> Stream m a
313intFromThenToUp from next to = Stream step EnumInit
315 {-# INLINE_LATE step #-}
321 else Yield from EnumStop
322 else -- from <= next <= to
323 let stride = next - from
324 in Skip $ EnumYield from stride (to - stride)
326 step _ (EnumYield x stride toMinus) =
329 then Yield x EnumStop
330 else Yield x $ EnumYield (x + stride) stride toMinus
332 step _ EnumStop = return Stop
334{-# INLINE_NORMAL intFromThenToDn #-}
335intFromThenToDn :: (Monad m, Integral a) => a -> a -> a -> Stream m a
336intFromThenToDn from next to = Stream step EnumInit
338 {-# INLINE_LATE step #-}
340 return $ if to > next
343 else Yield from EnumStop
344 else -- from >= next >= to
345 let stride = next - from
346 in Skip $ EnumYield from stride (to - stride)
348 step _ (EnumYield x stride toMinus) =
351 then Yield x EnumStop
352 else Yield x $ EnumYield (x + stride) stride toMinus
354 step _ EnumStop = return Stop
356{-# INLINE_NORMAL intFromThenTo #-}
357intFromThenTo :: (Monad m, Integral a) => a -> a -> a -> Stream m a
358intFromThenTo from next to
359 | next >= from = intFromThenToUp from next to
360 | otherwise = intFromThenToDn from next to
362{-# INLINE_NORMAL intFromThen #-}
363intFromThen :: (Monad m, Integral a, Bounded a) => a -> a -> Stream m a
364intFromThen from next =
366 then intFromThenToUp from next maxBound
367 else intFromThenToDn from next minBound
369-- For floating point numbers if the increment is less than the precision then
370-- it just gets lost. Therefore we cannot always increment it correctly by just
372-- 9007199254740992 + 1 + 1 :: Double => 9.007199254740992e15
373-- 9007199254740992 + 2 :: Double => 9.007199254740994e15
375-- Instead we accumulate the increment counter and compute the increment
376-- everytime before adding it to the starting number.
378-- This works for Integrals as well as floating point numbers, but intFromStep
379-- is faster for integrals.
380{-# INLINE_NORMAL numFromStep #-}
381numFromStep :: (Monad m, Num a) => a -> a -> Stream m a
382numFromStep from stride = Stream step 0
384 {-# INLINE_LATE step #-}
385 step _ !i = return $ (Yield $! (from + i * stride)) $! (i + 1)
387{-# INLINE_NORMAL numFrom #-}
388numFrom :: (Monad m, Num a) => a -> Stream m a
389numFrom from = numFromStep from 1
391{-# INLINE_NORMAL numFromThen #-}
392numFromThen :: (Monad m, Num a) => a -> a -> Stream m a
393numFromThen from next = numFromStep from (next - from)
395-- We cannot write a general function for Num. The only way to write code
396-- portable between the two is to use a 'Real' constraint and convert between
397-- Fractional and Integral using fromRational which is horribly slow.
398{-# INLINE_NORMAL fracFromTo #-}
399fracFromTo :: (Monad m, Fractional a, Ord a) => a -> a -> Stream m a
400fracFromTo from to = takeWhile (<= to + 1/2) $ numFromStep from 1
402{-# INLINE_NORMAL fracFromThenTo #-}
403fracFromThenTo :: (Monad m, Fractional a, Ord a) => a -> a -> a -> Stream m a
404fracFromThenTo from next to = takeWhile predicate $ numFromThen from next
406 mid = (next - from) / 2
407 predicate | next >= from = (<= to + mid)
408 | otherwise = (>= to + mid)
410-------------------------------------------------------------------------------
411-- Generation by Conversion
412-------------------------------------------------------------------------------
414-- | Create a singleton 'Stream' from a pure value.
415{-# INLINE_NORMAL yield #-}
416yield :: Monad m => a -> Stream m a
417yield x = Stream (\_ s -> return $ step undefined s) True
419 {-# INLINE_LATE step #-}
420 step _ True = Yield x False
423-- | Create a singleton 'Stream' from a monadic action.
424{-# INLINE_NORMAL yieldM #-}
425yieldM :: Monad m => m a -> Stream m a
426yieldM m = Stream step True
428 {-# INLINE_LATE step #-}
429 step _ True = m >>= \x -> return $ Yield x False
430 step _ False = return Stop
432{-# INLINE_NORMAL fromIndicesM #-}
433fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
434fromIndicesM gen = Stream step 0
436 {-# INLINE_LATE step #-}
439 return $ Yield x (i + 1)
441{-# INLINE fromIndices #-}
442fromIndices :: Monad m => (Int -> a) -> Stream m a
443fromIndices gen = fromIndicesM (return . gen)
445{-# INLINE_NORMAL generateM #-}
446generateM :: Monad m => Int -> (Int -> m a) -> Stream m a
447generateM n gen = n `seq` Stream step 0
449 {-# INLINE_LATE step #-}
450 step _ i | i < n = do
452 return $ Yield x (i + 1)
453 | otherwise = return Stop
455{-# INLINE generate #-}
456generate :: Monad m => Int -> (Int -> a) -> Stream m a
457generate n gen = generateM n (return . gen)
459-- XXX we need the MonadAsync constraint because of a rewrite rule.
460-- | Convert a list of monadic actions to a 'Stream'
461{-# INLINE_LATE fromListM #-}
462fromListM :: MonadAsync m => [m a] -> Stream m a
463fromListM = Stream step
465 {-# INLINE_LATE step #-}
466 step _ (m:ms) = m >>= \x -> return $ Yield x ms
467 step _ [] = return Stop
469-- | Convert a list of pure values to a 'Stream'
470{-# INLINE_LATE fromList #-}
471fromList :: Monad m => [a] -> Stream m a
472fromList = Stream step
474 {-# INLINE_LATE step #-}
475 step _ (x:xs) = return $ Yield x xs
476 step _ [] = return Stop
478{-# INLINE_LATE fromStreamK #-}
479fromStreamK :: Monad m => K.Stream m a -> Stream m a
480fromStreamK = Stream step
483 let stop = return Stop
484 single a = return $ Yield a K.nil
485 yieldk a r = return $ Yield a r
486 in K.foldStreamShared gst yieldk single stop m1
488{-# INLINE toStreamD #-}
489toStreamD :: (K.IsStream t, Monad m) => t m a -> Stream m a
490toStreamD = fromStreamK . K.toStream
492------------------------------------------------------------------------------
493-- Elimination by Folds
494------------------------------------------------------------------------------
496{-# INLINE_NORMAL foldrM #-}
497foldrM :: Monad m => (a -> b -> m b) -> b -> Stream m a -> m b
498foldrM f z (Stream step state) = go SPEC state
501 r <- step defState st
503 Yield x s -> go SPEC s >>= f x
507{-# INLINE_NORMAL foldr #-}
508foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b
509foldr f = foldrM (\a b -> return (f a b))
511{-# INLINE_NORMAL foldr1 #-}
512foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
516 Nothing -> return Nothing
517 Just (h, t) -> fmap Just (foldr f h t)
519{-# INLINE_NORMAL foldlM' #-}
520foldlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> m b
521foldlM' fstep begin (Stream step state) = go SPEC begin state
523 go !_ acc st = acc `seq` do
524 r <- step defState st
529 Skip s -> go SPEC acc s
533foldl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> m b
534foldl' fstep = foldlM' (\b a -> return (fstep b a))
536------------------------------------------------------------------------------
538------------------------------------------------------------------------------
540-- | Run a streaming composition, discard the results.
541{-# INLINE_LATE runStream #-}
542runStream :: Monad m => Stream m a -> m ()
543runStream (Stream step state) = go SPEC state
546 r <- step defState st
548 Yield _ s -> go SPEC s
552{-# INLINE_NORMAL null #-}
553null :: Monad m => Stream m a -> m Bool
554null (Stream step state) = go state
557 r <- step defState st
559 Yield _ _ -> return False
564{-# INLINE_NORMAL head #-}
565head :: Monad m => Stream m a -> m (Maybe a)
566head (Stream step state) = go state
569 r <- step defState st
571 Yield x _ -> return (Just x)
573 Stop -> return Nothing
575-- Does not fuse, has the same performance as the StreamK version.
576{-# INLINE_NORMAL tail #-}
577tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
578tail (UnStream step state) = go state
581 r <- step defState st
583 Yield _ s -> return (Just $ Stream step s)
585 Stop -> return Nothing
587-- XXX will it fuse? need custom impl?
588{-# INLINE_NORMAL last #-}
589last :: Monad m => Stream m a -> m (Maybe a)
590last = foldl' (\_ y -> Just y) Nothing
592{-# INLINE_NORMAL elem #-}
593elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
594elem e (Stream step state) = go state
597 r <- step defState st
600 | x == e -> return True
605{-# INLINE_NORMAL notElem #-}
606notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
607notElem e s = fmap not (elem e s)
609{-# INLINE_NORMAL all #-}
610all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
611all p (Stream step state) = go state
614 r <- step defState st
618 | otherwise -> return False
622{-# INLINE_NORMAL any #-}
623any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
624any p (Stream step state) = go state
627 r <- step defState st
635{-# INLINE_NORMAL maximum #-}
636maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
637maximum (Stream step state) = go Nothing state
640 r <- step defState st
642 Yield x s -> go (Just x) s
643 Skip s -> go Nothing s
644 Stop -> return Nothing
645 go (Just acc) st = do
646 r <- step defState st
649 | acc <= x -> go (Just x) s
650 | otherwise -> go (Just acc) s
651 Skip s -> go (Just acc) s
652 Stop -> return (Just acc)
654{-# INLINE_NORMAL maximumBy #-}
655maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
656maximumBy cmp (Stream step state) = go Nothing state
659 r <- step defState st
661 Yield x s -> go (Just x) s
662 Skip s -> go Nothing s
663 Stop -> return Nothing
664 go (Just acc) st = do
665 r <- step defState st
667 Yield x s -> case cmp acc x of
668 GT -> go (Just acc) s
670 Skip s -> go (Just acc) s
671 Stop -> return (Just acc)
673{-# INLINE_NORMAL minimum #-}
674minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
675minimum (Stream step state) = go Nothing state
678 r <- step defState st
680 Yield x s -> go (Just x) s
681 Skip s -> go Nothing s
682 Stop -> return Nothing
683 go (Just acc) st = do
684 r <- step defState st
687 | acc <= x -> go (Just acc) s
688 | otherwise -> go (Just x) s
689 Skip s -> go (Just acc) s
690 Stop -> return (Just acc)
692{-# INLINE_NORMAL minimumBy #-}
693minimumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
694minimumBy cmp (Stream step state) = go Nothing state
697 r <- step defState st
699 Yield x s -> go (Just x) s
700 Skip s -> go Nothing s
701 Stop -> return Nothing
702 go (Just acc) st = do
703 r <- step defState st
705 Yield x s -> case cmp acc x of
708 Skip s -> go (Just acc) s
709 Stop -> return (Just acc)
711{-# INLINE_NORMAL (!!) #-}
712(!!) :: (Monad m) => Stream m a -> Int -> m (Maybe a)
713(Stream step state) !! i = go i state
716 r <- step defState st
718 Yield x s | n < 0 -> return Nothing
719 | n == 0 -> return $ Just x
720 | otherwise -> go (n - 1) s
722 Stop -> return Nothing
724{-# INLINE_NORMAL lookup #-}
725lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
726lookup e (Stream step state) = go state
729 r <- step defState st
731 Yield (a, b) s -> if e == a then return (Just b) else go s
733 Stop -> return Nothing
735{-# INLINE_NORMAL findM #-}
736findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
737findM p (Stream step state) = go SPEC state
740 r <- step defState st
744 if b then return (Just x) else go SPEC s
746 Stop -> return Nothing
749find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
750find p = findM (return . p)
752{-# INLINE_NORMAL findIndices #-}
753findIndices :: Monad m => (a -> Bool) -> Stream m a -> Stream m Int
754findIndices p (Stream step state) = Stream step' (state, 0)
756 {-# INLINE_LATE step' #-}
757 step' gst (st, i) = do
758 r <- step (adaptState gst) st
760 Yield x s -> if p x then Yield i (s, i+1) else Skip (s, i+1)
761 Skip s -> Skip (s, i+1)
764{-# INLINE_NORMAL concatMapM #-}
765concatMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b
766concatMapM f (Stream step state) = Stream step' (Left state)
768 {-# INLINE_LATE step' #-}
769 step' gst (Left st) = do
770 r <- step (adaptState gst) st
774 return $ Skip (Right (b_stream, s))
775 Skip s -> return $ Skip (Left s)
778 -- XXX using the pattern synonym Stream causes a major performance issue
779 -- here even if the synonym does not include a adaptState call. Need to
780 -- find out why. Is that something to be fixed in GHC?
781 step' _ (Right (UnStream inner_step inner_st, st)) = do
782 r <- inner_step defState inner_st
785 return $ Yield b (Right (Stream inner_step inner_s, st))
787 return $ Skip (Right (Stream inner_step inner_s, st))
788 Stop -> return $ Skip (Left st)
790{-# INLINE concatMap #-}
791concatMap :: Monad m => (a -> Stream m b) -> Stream m a -> Stream m b
792concatMap f = concatMapM (return . f)
794------------------------------------------------------------------------------
796------------------------------------------------------------------------------
798{-# INLINE_NORMAL isPrefixOf #-}
799isPrefixOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
800isPrefixOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
802 go (sa, sb, Nothing) = do
803 r <- stepa defState sa
805 Yield x sa' -> go (sa', sb, Just x)
806 Skip sa' -> go (sa', sb, Nothing)
809 go (sa, sb, Just x) = do
810 r <- stepb defState sb
814 then go (sa, sb', Nothing)
816 Skip sb' -> go (sa, sb', Just x)
819{-# INLINE_NORMAL isSubsequenceOf #-}
820isSubsequenceOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
821isSubsequenceOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
823 go (sa, sb, Nothing) = do
824 r <- stepa defState sa
826 Yield x sa' -> go (sa', sb, Just x)
827 Skip sa' -> go (sa', sb, Nothing)
830 go (sa, sb, Just x) = do
831 r <- stepb defState sb
835 then go (sa, sb', Nothing)
836 else go (sa, sb', Just x)
837 Skip sb' -> go (sa, sb', Just x)
840{-# INLINE_NORMAL stripPrefix #-}
843 => Stream m a -> Stream m a -> m (Maybe (Stream m a))
844stripPrefix (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
846 go (sa, sb, Nothing) = do
847 r <- stepa defState sa
849 Yield x sa' -> go (sa', sb, Just x)
850 Skip sa' -> go (sa', sb, Nothing)
851 Stop -> return $ Just (Stream stepb sb)
853 go (sa, sb, Just x) = do
854 r <- stepb defState sb
858 then go (sa, sb', Nothing)
860 Skip sb' -> go (sa, sb', Just x)
861 Stop -> return Nothing
863------------------------------------------------------------------------------
865------------------------------------------------------------------------------
867-- | Execute a monadic action for each element of the 'Stream'
868{-# INLINE_NORMAL mapM_ #-}
869mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
870mapM_ m = runStream . mapM m
872------------------------------------------------------------------------------
874------------------------------------------------------------------------------
877toList :: Monad m => Stream m a -> m [a]
880-- Convert a direct stream to and from CPS encoded stream
881{-# INLINE_LATE toStreamK #-}
882toStreamK :: Monad m => Stream m a -> K.Stream m a
883toStreamK (Stream step state) = go state
885 go st = K.mkStream $ \gst yld sng stp -> do
888 Yield x s -> yld x (go s)
889 Skip s -> K.foldStreamShared gst yld sng stp $ go s
892#ifndef DISABLE_FUSION
893{-# RULES "fromStreamK/toStreamK fusion"
894 forall s. toStreamK (fromStreamK s) = s #-}
895{-# RULES "toStreamK/fromStreamK fusion"
896 forall s. fromStreamK (toStreamK s) = s #-}
899{-# INLINE fromStreamD #-}
900fromStreamD :: (K.IsStream t, Monad m) => Stream m a -> t m a
901fromStreamD = K.fromStream . toStreamK
903------------------------------------------------------------------------------
904-- Transformation by Folding (Scans)
905------------------------------------------------------------------------------
907-- XXX Is a prescan useful, discarding the last step does not sound useful? I
908-- am not sure about the utility of this function, so this is implemented but
909-- not exposed. We can expose it if someone provides good reasons why this is
912-- XXX We have to execute the stream one step ahead to know that we are at the
913-- last step. The vector implementation of prescan executes the last fold step
914-- but does not yield the result. This means we have executed the effect but
915-- discarded value. This does not sound right. In this implementation we are
916-- not executing the last fold step.
917{-# INLINE_NORMAL prescanlM' #-}
918prescanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
919prescanlM' f mz (Stream step state) = Stream step' (state, mz)
921 {-# INLINE_LATE step' #-}
922 step' gst (st, prev) = do
923 r <- step (adaptState gst) st
927 return $ Yield acc (s, f acc x)
928 Skip s -> return $ Skip (s, prev)
931{-# INLINE prescanl' #-}
932prescanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
933prescanl' f z = prescanlM' (\a b -> return (f a b)) (return z)
935-- XXX if we make the initial value of the accumulator monadic then should we
936-- execute it even if the stream is empty? In that case we would have generated
937-- the effect but discarded the value, but that is what a fold does when the
938-- stream is empty. Whatever we decide, need to reconcile this with prescan.
939-- If we execute the initial value here without even using it then it is ok to
940-- execute the last step there as well without using the value.
941-- Looking at the duality with right fold, in case of right fold we always
942-- perform the action when the construction terminates, so in case of left fold
943-- we should perform it only when the reduction starts.
944{-# INLINE_NORMAL postscanlM' #-}
945postscanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
946postscanlM' fstep begin (Stream step state) =
947 begin `seq` Stream step' (state, begin)
949 {-# INLINE_LATE step' #-}
950 step' gst (st, acc) = acc `seq` do
951 r <- step (adaptState gst) st
955 y `seq` return (Yield y (s, y))
956 Skip s -> return $ Skip (s, acc)
959{-# INLINE_NORMAL postscanl' #-}
960postscanl' :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
961postscanl' f = postscanlM' (\a b -> return (f a b))
963{-# INLINE_NORMAL postscanlM #-}
964postscanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
965postscanlM fstep begin (Stream step state) = Stream step' (state, begin)
967 {-# INLINE_LATE step' #-}
968 step' gst (st, acc) = do
969 r <- step (adaptState gst) st
973 return (Yield y (s, y))
974 Skip s -> return $ Skip (s, acc)
977{-# INLINE_NORMAL postscanl #-}
978postscanl :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
979postscanl f = postscanlM (\a b -> return (f a b))
981{-# INLINE_NORMAL scanlM' #-}
982scanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
983scanlM' fstep begin s = begin `seq` (begin `cons` postscanlM' fstep begin s)
986scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
987scanl' f = scanlM' (\a b -> return (f a b))
989{-# INLINE_NORMAL scanlM #-}
990scanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
991scanlM fstep begin s = begin `cons` postscanlM fstep begin s
994scanl :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
995scanl f = scanlM (\a b -> return (f a b))
997{-# INLINE_NORMAL scanl1M #-}
998scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
999scanl1M fstep (Stream step state) = Stream step' (state, Nothing)
1001 {-# INLINE_LATE step' #-}
1002 step' gst (st, Nothing) = do
1005 Yield x s -> return $ Yield x (s, Just x)
1006 Skip s -> return $ Skip (s, Nothing)
1009 step' gst (st, Just acc) = do
1014 return $ Yield z (s, Just z)
1015 Skip s -> return $ Skip (s, Just acc)
1018{-# INLINE scanl1 #-}
1019scanl1 :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
1020scanl1 f = scanl1M (\x y -> return (f x y))
1022{-# INLINE_NORMAL scanl1M' #-}
1023scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
1024scanl1M' fstep (Stream step state) = Stream step' (state, Nothing)
1026 {-# INLINE_LATE step' #-}
1027 step' gst (st, Nothing) = do
1030 Yield x s -> x `seq` return $ Yield x (s, Just x)
1031 Skip s -> return $ Skip (s, Nothing)
1034 step' gst (st, Just acc) = acc `seq` do
1039 z `seq` return $ Yield z (s, Just z)
1040 Skip s -> return $ Skip (s, Just acc)
1043{-# INLINE scanl1' #-}
1044scanl1' :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
1045scanl1' f = scanl1M' (\x y -> return (f x y))
1047-------------------------------------------------------------------------------
1049-------------------------------------------------------------------------------
1051{-# INLINE_NORMAL take #-}
1052take :: Monad m => Int -> Stream m a -> Stream m a
1053take n (Stream step state) = n `seq` Stream step' (state, 0)
1055 {-# INLINE_LATE step' #-}
1056 step' gst (st, i) | i < n = do
1059 Yield x s -> Yield x (s, i + 1)
1060 Skip s -> Skip (s, i)
1062 step' _ (_, _) = return Stop
1064{-# INLINE_NORMAL takeWhileM #-}
1065takeWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
1066takeWhileM f (Stream step state) = Stream step' state
1068 {-# INLINE_LATE step' #-}
1074 return $ if b then Yield x s else Stop
1075 Skip s -> return $ Skip s
1078{-# INLINE takeWhile #-}
1079takeWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
1080takeWhile f = takeWhileM (return . f)
1082{-# INLINE_NORMAL drop #-}
1083drop :: Monad m => Int -> Stream m a -> Stream m a
1084drop n (Stream step state) = Stream step' (state, Just n)
1086 {-# INLINE_LATE step' #-}
1087 step' gst (st, Just i)
1092 Yield _ s -> Skip (s, Just (i - 1))
1093 Skip s -> Skip (s, Just i)
1095 | otherwise = return $ Skip (st, Nothing)
1097 step' gst (st, Nothing) = do
1101 Yield x s -> Yield x (s, Nothing)
1102 Skip s -> Skip (s, Nothing)
1105data DropWhileState s a
1107 | DropWhileYield a s
1110{-# INLINE_NORMAL dropWhileM #-}
1111dropWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
1112dropWhileM f (Stream step state) = Stream step' (DropWhileDrop state)
1114 {-# INLINE_LATE step' #-}
1115 step' gst (DropWhileDrop st) = do
1121 then return $ Skip (DropWhileDrop s)
1122 else return $ Skip (DropWhileYield x s)
1123 Skip s -> return $ Skip (DropWhileDrop s)
1126 step' gst (DropWhileNext st) = do
1129 Yield x s -> return $ Skip (DropWhileYield x s)
1130 Skip s -> return $ Skip (DropWhileNext s)
1133 step' _ (DropWhileYield x st) = return $ Yield x (DropWhileNext st)
1135{-# INLINE dropWhile #-}
1136dropWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
1137dropWhile f = dropWhileM (return . f)
1139{-# INLINE_NORMAL filterM #-}
1140filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
1141filterM f (Stream step state) = Stream step' state
1143 {-# INLINE_LATE step' #-}
1152 Skip s -> return $ Skip s
1155{-# INLINE filter #-}
1156filter :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
1157filter f = filterM (return . f)
1159{-# INLINE_NORMAL uniq #-}
1160uniq :: (Eq a, Monad m) => Stream m a -> Stream m a
1161uniq (Stream step state) = Stream step' (Nothing, state)
1163 {-# INLINE_LATE step' #-}
1164 step' gst (Nothing, st) = do
1167 Yield x s -> return $ Yield x (Just x, s)
1168 Skip s -> return $ Skip (Nothing, s)
1170 step' gst (Just x, st) = do
1173 Yield y s | x == y -> return $ Skip (Just x, s)
1174 | otherwise -> return $ Yield x (Just y, s)
1175 Skip s -> return $ Skip (Just x, s)
1178------------------------------------------------------------------------------
1179-- Transformation by Mapping
1180------------------------------------------------------------------------------
1182{-# INLINE_NORMAL sequence #-}
1183sequence :: Monad m => Stream m (m a) -> Stream m a
1184sequence (Stream step state) = Stream step' state
1186 {-# INLINE_LATE step' #-}
1188 r <- step (adaptState gst) st
1190 Yield x s -> x >>= \a -> return (Yield a s)
1191 Skip s -> return $ Skip s
1194------------------------------------------------------------------------------
1196------------------------------------------------------------------------------
1198{-# INLINE_NORMAL insertBy #-}
1199insertBy :: Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
1200insertBy cmp a (Stream step state) = Stream step' (state, False, Nothing)
1202 {-# INLINE_LATE step' #-}
1203 step' gst (st, False, _) = do
1206 Yield x s -> case cmp a x of
1207 GT -> return $ Yield x (s, False, Nothing)
1208 _ -> return $ Yield a (s, True, Just x)
1209 Skip s -> return $ Skip (s, False, Nothing)
1210 Stop -> return $ Yield a (st, True, Nothing)
1212 step' _ (_, True, Nothing) = return Stop
1214 step' gst (st, True, Just prev) = do
1217 Yield x s -> return $ Yield prev (s, True, Just x)
1218 Skip s -> return $ Skip (s, True, Just prev)
1219 Stop -> return $ Yield prev (st, True, Nothing)
1221------------------------------------------------------------------------------
1223------------------------------------------------------------------------------
1225{-# INLINE_NORMAL deleteBy #-}
1226deleteBy :: Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a
1227deleteBy eq x (Stream step state) = Stream step' (state, False)
1229 {-# INLINE_LATE step' #-}
1230 step' gst (st, False) = do
1233 Yield y s -> return $
1234 if eq x y then Skip (s, True) else Yield y (s, False)
1235 Skip s -> return $ Skip (s, False)
1238 step' gst (st, True) = do
1241 Yield y s -> return $ Yield y (s, True)
1242 Skip s -> return $ Skip (s, True)
1245------------------------------------------------------------------------------
1246-- Transformation by Map and Filter
1247------------------------------------------------------------------------------
1249-- XXX Will this always fuse properly?
1250{-# INLINE_NORMAL mapMaybe #-}
1251mapMaybe :: Monad m => (a -> Maybe b) -> Stream m a -> Stream m b
1252mapMaybe f = fmap fromJust . filter isJust . map f
1254{-# INLINE_NORMAL mapMaybeM #-}
1255mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b
1256mapMaybeM f = fmap fromJust . filter isJust . mapM f
1258------------------------------------------------------------------------------
1260------------------------------------------------------------------------------
1262{-# INLINE_NORMAL indexed #-}
1263indexed :: Monad m => Stream m a -> Stream m (Int, a)
1264indexed (Stream step state) = Stream step' (state, 0)
1266 {-# INLINE_LATE step' #-}
1267 step' gst (st, i) = i `seq` do
1268 r <- step (adaptState gst) st
1270 Yield x s -> return $ Yield (i, x) (s, i+1)
1271 Skip s -> return $ Skip (s, i)
1274{-# INLINE_NORMAL indexedR #-}
1275indexedR :: Monad m => Int -> Stream m a -> Stream m (Int, a)
1276indexedR m (Stream step state) = Stream step' (state, m)
1278 {-# INLINE_LATE step' #-}
1279 step' gst (st, i) = i `seq` do
1280 r <- step (adaptState gst) st
1282 Yield x s -> let i' = i - 1
1284 return $ Yield (i', x) (s, i')
1285 Skip s -> return $ Skip (s, i)
1288{-# INLINE_NORMAL zipWithM #-}
1290 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
1291zipWithM f (Stream stepa ta) (Stream stepb tb) = Stream step (ta, tb, Nothing)
1293 {-# INLINE_LATE step #-}
1294 step gst (sa, sb, Nothing) = do
1295 r <- stepa (adaptState gst) sa
1298 Yield x sa' -> Skip (sa', sb, Just x)
1299 Skip sa' -> Skip (sa', sb, Nothing)
1302 step gst (sa, sb, Just x) = do
1303 r <- stepb (adaptState gst) sb
1307 return $ Yield z (sa, sb', Nothing)
1308 Skip sb' -> return $ Skip (sa, sb', Just x)
1311{-# RULES "zipWithM xs xs"
1312 forall f xs. zipWithM f xs xs = mapM (\x -> f x x) xs #-}
1314{-# INLINE zipWith #-}
1315zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
1316zipWith f = zipWithM (\a b -> return (f a b))
1318------------------------------------------------------------------------------
1320------------------------------------------------------------------------------
1322{-# INLINE_NORMAL eqBy #-}
1323eqBy :: Monad m => (a -> b -> Bool) -> Stream m a -> Stream m b -> m Bool
1324eqBy eq (Stream step1 t1) (Stream step2 t2) = eq_loop0 SPEC t1 t2
1326 eq_loop0 !_ s1 s2 = do
1327 r <- step1 defState s1
1329 Yield x s1' -> eq_loop1 SPEC x s1' s2
1330 Skip s1' -> eq_loop0 SPEC s1' s2
1333 eq_loop1 !_ x s1 s2 = do
1334 r <- step2 defState s2
1337 | eq x y -> eq_loop0 SPEC s1 s2'
1338 | otherwise -> return False
1339 Skip s2' -> eq_loop1 SPEC x s1 s2'
1340 Stop -> return False
1343 r <- step2 defState s2
1345 Yield _ _ -> return False
1346 Skip s2' -> eq_null s2'
1349-- | Compare two streams lexicographically
1350{-# INLINE_NORMAL cmpBy #-}
1353 => (a -> b -> Ordering) -> Stream m a -> Stream m b -> m Ordering
1354cmpBy cmp (Stream step1 t1) (Stream step2 t2) = cmp_loop0 SPEC t1 t2
1356 cmp_loop0 !_ s1 s2 = do
1357 r <- step1 defState s1
1359 Yield x s1' -> cmp_loop1 SPEC x s1' s2
1360 Skip s1' -> cmp_loop0 SPEC s1' s2
1363 cmp_loop1 !_ x s1 s2 = do
1364 r <- step2 defState s2
1366 Yield y s2' -> case x `cmp` y of
1367 EQ -> cmp_loop0 SPEC s1 s2'
1369 Skip s2' -> cmp_loop1 SPEC x s1 s2'
1373 r <- step2 defState s2
1375 Yield _ _ -> return LT
1376 Skip s2' -> cmp_null s2'
1379------------------------------------------------------------------------------
1381------------------------------------------------------------------------------
1383{-# INLINE_NORMAL mergeByM #-}
1386 => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
1387mergeByM cmp (Stream stepa ta) (Stream stepb tb) =
1388 Stream step (Just ta, Just tb, Nothing, Nothing)
1390 {-# INLINE_LATE step #-}
1392 -- one of the values is missing, and the corresponding stream is running
1393 step gst (Just sa, sb, Nothing, b) = do
1396 Yield a sa' -> Skip (Just sa', sb, Just a, b)
1397 Skip sa' -> Skip (Just sa', sb, Nothing, b)
1398 Stop -> Skip (Nothing, sb, Nothing, b)
1400 step gst (sa, Just sb, a, Nothing) = do
1403 Yield b sb' -> Skip (sa, Just sb', a, Just b)
1404 Skip sb' -> Skip (sa, Just sb', a, Nothing)
1405 Stop -> Skip (sa, Nothing, a, Nothing)
1407 -- both the values are available
1408 step _ (sa, sb, Just a, Just b) = do
1410 return $ case res of
1411 GT -> Yield b (sa, sb, Just a, Nothing)
1412 _ -> Yield a (sa, sb, Nothing, Just b)
1414 -- one of the values is missing, corresponding stream is done
1415 step _ (Nothing, sb, Nothing, Just b) =
1416 return $ Yield b (Nothing, sb, Nothing, Nothing)
1418 step _ (sa, Nothing, Just a, Nothing) =
1419 return $ Yield a (sa, Nothing, Nothing, Nothing)
1421 step _ (Nothing, Nothing, Nothing, Nothing) = return Stop
1423{-# INLINE mergeBy #-}
1426 => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
1427mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
1429------------------------------------------------------------------------------
1430-- Transformation comprehensions
1431------------------------------------------------------------------------------
1433{-# INLINE_NORMAL the #-}
1434the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
1435the (Stream step state) = go state
1438 r <- step defState st
1440 Yield x s -> go' x s
1442 Stop -> return Nothing
1444 r <- step defState st
1446 Yield x s | x == n -> go' n s
1447 | otherwise -> return Nothing
1449 Stop -> return (Just n)
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