on 665e7df help sign in
4038 lines 139 kB history raw
1{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE CPP #-}
3{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE ExistentialQuantification #-}
5{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE PatternSynonyms #-}
9{-# LANGUAGE RecordWildCards #-}
10{-# LANGUAGE ScopedTypeVariables #-}
11{-# LANGUAGE ViewPatterns #-}
12{-# LANGUAGE RankNTypes #-}
13{-# LANGUAGE MagicHash #-}
15#if __GLASGOW_HASKELL__ >= 801
16{-# LANGUAGE TypeApplications #-}
17#endif
19#include "inline.hs"
21-- |
22-- Module : Streamly.Internal.Data.Stream.StreamD
23-- Copyright : (c) 2018 Harendra Kumar
24-- Copyright : (c) Roman Leshchinskiy 2008-2010
25-- Copyright : (c) The University of Glasgow, 2009
26-- Copyright : (c) Bjoern Hoehrmann 2008-2009
27--
28-- License : BSD3
29-- Maintainer : streamly@composewell.com
30-- Stability : experimental
31-- Portability : GHC
32--
33-- Direct style re-implementation of CPS style stream in StreamK module. The
34-- symbol or suffix 'D' in this module denotes the "Direct" style. GHC is able
35-- to INLINE and fuse direct style better, providing better performance than
36-- CPS implementation.
37--
38-- @
39-- import qualified Streamly.Internal.Data.Stream.StreamD as D
40-- @
42-- Some of the functions in this file have been adapted from the vector
43-- library, https://hackage.haskell.org/package/vector.
45module Streamly.Internal.Data.Stream.StreamD
46 (
47 -- * The stream type
48 Step (..)
50#if __GLASGOW_HASKELL__ >= 800
51 , Stream (Stream, UnStream)
52#else
53 , Stream (UnStream)
54 , pattern Stream
55#endif
57 -- * Construction
58 , nil
59 , nilM
60 , cons
62 -- * Deconstruction
63 , uncons
65 -- * Generation
66 -- ** Unfolds
67 , unfoldr
68 , unfoldrM
69 , unfold
71 -- ** Specialized Generation
72 -- | Generate a monadic stream from a seed.
73 , repeat
74 , repeatM
75 , replicate
76 , replicateM
77 , fromIndices
78 , fromIndicesM
79 , generate
80 , generateM
81 , iterate
82 , iterateM
84 -- ** Enumerations
85 , enumerateFromStepIntegral
86 , enumerateFromIntegral
87 , enumerateFromThenIntegral
88 , enumerateFromToIntegral
89 , enumerateFromThenToIntegral
91 , enumerateFromStepNum
92 , numFrom
93 , numFromThen
94 , enumerateFromToFractional
95 , enumerateFromThenToFractional
97 -- ** Conversions
98 -- | Transform an input structure into a stream.
99 -- | Direct style stream does not support @fromFoldable@.
100 , yield
101 , yieldM
102 , fromList
103 , fromListM
104 , fromStreamK
105 , fromStreamD
106 , fromPrimVar
107 , fromSVar
109 -- * Elimination
110 -- ** General Folds
111 , foldrS
112 , foldrT
113 , foldrM
114 , foldrMx
115 , foldr
116 , foldr1
118 , foldl'
119 , foldlM'
120 , foldlS
121 , foldlT
122 , reverse
123 , reverse'
125 , foldlx'
126 , foldlMx'
127 , runFold
129 -- ** Specialized Folds
130 , tap
131 , tapOffsetEvery
132 , tapAsync
133 , tapRate
134 , pollCounts
135 , drain
136 , null
137 , head
138 , headElse
139 , tail
140 , last
141 , elem
142 , notElem
143 , all
144 , any
145 , maximum
146 , maximumBy
147 , minimum
148 , minimumBy
149 , findIndices
150 , lookup
151 , findM
152 , find
153 , (!!)
154 , toSVarParallel
156 -- ** Flattening nested streams
157 , concatMapM
158 , concatMap
159 , ConcatMapUState (..)
160 , concatMapU
161 , ConcatUnfoldInterleaveState (..)
162 , concatUnfoldInterleave
163 , concatUnfoldRoundrobin
164 , AppendState(..)
165 , append
166 , InterleaveState(..)
167 , interleave
168 , interleaveMin
169 , interleaveSuffix
170 , interleaveInfix
171 , roundRobin -- interleaveFair?/ParallelFair
172 , gintercalateSuffix
173 , interposeSuffix
174 , gintercalate
175 , interpose
177 -- ** Grouping
178 , groupsOf
179 , groupsOf2
180 , groupsBy
181 , groupsRollingBy
183 -- ** Splitting
184 , splitBy
185 , splitSuffixBy
186 , wordsBy
187 , splitSuffixBy'
189 , splitOn
190 , splitSuffixOn
192 , splitInnerBy
193 , splitInnerBySuffix
195 -- ** Substreams
196 , isPrefixOf
197 , isSubsequenceOf
198 , stripPrefix
200 -- ** Map and Fold
201 , mapM_
203 -- ** Conversions
204 -- | Transform a stream into another type.
205 , toList
206 , toListRev
207 , toStreamK
208 , toStreamD
210 , hoist
211 , generally
213 , liftInner
214 , runReaderT
215 , evalStateT
216 , runStateT
218 -- * Transformation
219 , transform
221 -- ** By folding (scans)
222 , scanlM'
223 , scanl'
224 , scanlM
225 , scanl
226 , scanl1M'
227 , scanl1'
228 , scanl1M
229 , scanl1
231 , prescanl'
232 , prescanlM'
234 , postscanl
235 , postscanlM
236 , postscanl'
237 , postscanlM'
239 , postscanlx'
240 , postscanlMx'
241 , scanlMx'
242 , scanlx'
244 -- * Filtering
245 , filter
246 , filterM
247 , uniq
248 , take
249 , takeWhile
250 , takeWhileM
251 , drop
252 , dropWhile
253 , dropWhileM
255 -- * Mapping
256 , map
257 , mapM
258 , sequence
259 , rollingMap
260 , rollingMapM
262 -- * Inserting
263 , intersperseM
264 , intersperse
265 , intersperseSuffix
266 , intersperseSuffixBySpan
267 , insertBy
269 -- * Deleting
270 , deleteBy
272 -- ** Map and Filter
273 , mapMaybe
274 , mapMaybeM
276 -- * Zipping
277 , indexed
278 , indexedR
279 , zipWith
280 , zipWithM
281 , zipAsyncWith
282 , zipAsyncWithM
284 -- * Comparisons
285 , eqBy
286 , cmpBy
288 -- * Merging
289 , mergeBy
290 , mergeByM
292 -- * Transformation comprehensions
293 , the
295 -- * Exceptions
296 , gbracket
297 , before
298 , after
299 , bracket
300 , onException
301 , finally
302 , handle
304 -- * Concurrent Application
305 , mkParallel
306 , applyParallel
307 , foldParallel
309 -- XXX Move this later
310 -- XXX Exported from Array again
311 , lastN
312 )
313where
315import Control.Concurrent (killThread, myThreadId, takeMVar, threadDelay)
316import Control.Exception
317 (Exception, SomeException, AsyncException, fromException)
318import Control.Monad (void, when)
319import Control.Monad.Catch (MonadCatch, throwM)
320import Control.Monad.IO.Class (MonadIO(..))
321import Control.Monad.Reader (ReaderT)
322import Control.Monad.State.Strict (StateT)
323import Control.Monad.Trans (MonadTrans(lift))
324import Data.Bits (shiftR, shiftL, (.|.), (.&.))
325import Data.Functor.Identity (Identity(..))
326import Data.IORef (newIORef, readIORef, mkWeakIORef, writeIORef)
327import Data.Maybe (fromJust, isJust, isNothing)
328import Data.Word (Word32)
329import Foreign.Ptr (Ptr)
330import Foreign.Storable (Storable(..))
331import GHC.Types (SPEC(..))
332import System.Mem (performMajorGC)
333import Prelude
334 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
335 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
336 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
337 (!!), scanl, scanl1, concatMap, replicate, enumFromTo, concat,
338 reverse, iterate)
340import qualified Control.Monad.Catch as MC
341import qualified Control.Monad.Reader as Reader
342import qualified Control.Monad.State.Strict as State
343import qualified Prelude
345import Streamly.Internal.Mutable.Prim.Var
346 (Prim, Var, readVar, newVar, modifyVar')
347import Streamly.Internal.Data.Atomics (atomicModifyIORefCAS_)
348import Streamly.Internal.Memory.Array.Types (Array(..))
349import Streamly.Internal.Data.Fold.Types (Fold(..))
350import Streamly.Internal.Data.Pipe.Types (Pipe(..), PipeState(..))
351import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
352import Streamly.Internal.Data.Unfold.Types (Unfold(..))
353import Streamly.Internal.Data.Strict (Tuple3'(..))
355import Streamly.Internal.Data.Stream.StreamD.Type
356import Streamly.Internal.Data.SVar
357import Streamly.Internal.Data.Stream.SVar (fromConsumer, pushToFold)
359import qualified Streamly.Internal.Data.Pipe.Types as Pipe
360import qualified Streamly.Internal.Memory.Array.Types as A
361import qualified Streamly.Internal.Data.Fold as FL
362import qualified Streamly.Memory.Ring as RB
363import qualified Streamly.Internal.Data.Stream.StreamK as K
365------------------------------------------------------------------------------
366-- Construction
367------------------------------------------------------------------------------
369-- | An empty 'Stream'.
370{-# INLINE_NORMAL nil #-}
371nil :: Monad m => Stream m a
372nil = Stream (\_ _ -> return Stop) ()
374-- | An empty 'Stream' with a side effect.
375{-# INLINE_NORMAL nilM #-}
376nilM :: Monad m => m b -> Stream m a
377nilM m = Stream (\_ _ -> m >> return Stop) ()
379{-# INLINE_NORMAL consM #-}
380consM :: Monad m => m a -> Stream m a -> Stream m a
381consM m (Stream step state) = Stream step1 Nothing
382 where
383 {-# INLINE_LATE step1 #-}
384 step1 _ Nothing = m >>= \x -> return $ Yield x (Just state)
385 step1 gst (Just st) = do
386 r <- step gst st
387 return $
388 case r of
389 Yield a s -> Yield a (Just s)
390 Skip s -> Skip (Just s)
391 Stop -> Stop
393-- XXX implement in terms of consM?
394-- cons x = consM (return x)
395--
396-- | Can fuse but has O(n^2) complexity.
397{-# INLINE_NORMAL cons #-}
398cons :: Monad m => a -> Stream m a -> Stream m a
399cons x (Stream step state) = Stream step1 Nothing
400 where
401 {-# INLINE_LATE step1 #-}
402 step1 _ Nothing = return $ Yield x (Just state)
403 step1 gst (Just st) = do
404 r <- step gst st
405 return $
406 case r of
407 Yield a s -> Yield a (Just s)
408 Skip s -> Skip (Just s)
409 Stop -> Stop
411-------------------------------------------------------------------------------
412-- Deconstruction
413-------------------------------------------------------------------------------
415-- Does not fuse, has the same performance as the StreamK version.
416{-# INLINE_NORMAL uncons #-}
417uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
418uncons (UnStream step state) = go state
419 where
420 go st = do
421 r <- step defState st
422 case r of
423 Yield x s -> return $ Just (x, Stream step s)
424 Skip s -> go s
425 Stop -> return Nothing
427------------------------------------------------------------------------------
428-- Generation by unfold
429------------------------------------------------------------------------------
431{-# INLINE_NORMAL unfoldrM #-}
432unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
433unfoldrM next state = Stream step state
434 where
435 {-# INLINE_LATE step #-}
436 step _ st = do
437 r <- next st
438 return $ case r of
439 Just (x, s) -> Yield x s
440 Nothing -> Stop
442{-# INLINE_LATE unfoldr #-}
443unfoldr :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a
444unfoldr f = unfoldrM (return . f)
446-- | Convert an 'Unfold' into a 'Stream' by supplying it a seed.
447--
448{-# INLINE_NORMAL unfold #-}
449unfold :: Monad m => Unfold m a b -> a -> Stream m b
450unfold (Unfold ustep inject) seed = Stream step Nothing
451 where
452 {-# INLINE_LATE step #-}
453 step _ Nothing = inject seed >>= return . Skip . Just
454 step _ (Just st) = do
455 r <- ustep st
456 return $ case r of
457 Yield x s -> Yield x (Just s)
458 Skip s -> Skip (Just s)
459 Stop -> Stop
461------------------------------------------------------------------------------
462-- Specialized Generation
463------------------------------------------------------------------------------
465{-# INLINE_NORMAL repeatM #-}
466repeatM :: Monad m => m a -> Stream m a
467repeatM x = Stream (\_ _ -> x >>= \r -> return $ Yield r ()) ()
469{-# INLINE_NORMAL repeat #-}
470repeat :: Monad m => a -> Stream m a
471repeat x = Stream (\_ _ -> return $ Yield x ()) ()
473{-# INLINE_NORMAL iterateM #-}
474iterateM :: Monad m => (a -> m a) -> m a -> Stream m a
475iterateM step = Stream (\_ st -> st >>= \x -> return $ Yield x (step x))
477{-# INLINE_NORMAL iterate #-}
478iterate :: Monad m => (a -> a) -> a -> Stream m a
479iterate step st = iterateM (return . step) (return st)
481{-# INLINE_NORMAL replicateM #-}
482replicateM :: forall m a. Monad m => Int -> m a -> Stream m a
483replicateM n p = Stream step n
484 where
485 {-# INLINE_LATE step #-}
486 step _ (i :: Int)
487 | i <= 0 = return Stop
488 | otherwise = do
489 x <- p
490 return $ Yield x (i - 1)
492{-# INLINE_NORMAL replicate #-}
493replicate :: Monad m => Int -> a -> Stream m a
494replicate n x = replicateM n (return x)
496-- This would not work properly for floats, therefore we put an Integral
497-- constraint.
498-- | Can be used to enumerate unbounded integrals. This does not check for
499-- overflow or underflow for bounded integrals.
500{-# INLINE_NORMAL enumerateFromStepIntegral #-}
501enumerateFromStepIntegral :: (Integral a, Monad m) => a -> a -> Stream m a
502enumerateFromStepIntegral from stride =
503 from `seq` stride `seq` Stream step from
504 where
505 {-# INLINE_LATE step #-}
506 step _ !x = return $ Yield x $! (x + stride)
508-- We are assuming that "to" is constrained by the type to be within
509-- max/min bounds.
510{-# INLINE enumerateFromToIntegral #-}
511enumerateFromToIntegral :: (Monad m, Integral a) => a -> a -> Stream m a
512enumerateFromToIntegral from to =
513 takeWhile (<= to) $ enumerateFromStepIntegral from 1
515{-# INLINE enumerateFromIntegral #-}
516enumerateFromIntegral :: (Monad m, Integral a, Bounded a) => a -> Stream m a
517enumerateFromIntegral from = enumerateFromToIntegral from maxBound
519data EnumState a = EnumInit | EnumYield a a a | EnumStop
521{-# INLINE_NORMAL enumerateFromThenToIntegralUp #-}
522enumerateFromThenToIntegralUp
523 :: (Monad m, Integral a)
524 => a -> a -> a -> Stream m a
525enumerateFromThenToIntegralUp from next to = Stream step EnumInit
526 where
527 {-# INLINE_LATE step #-}
528 step _ EnumInit =
529 return $
530 if to < next
531 then if to < from
532 then Stop
533 else Yield from EnumStop
534 else -- from <= next <= to
535 let stride = next - from
536 in Skip $ EnumYield from stride (to - stride)
538 step _ (EnumYield x stride toMinus) =
539 return $
540 if x > toMinus
541 then Yield x EnumStop
542 else Yield x $ EnumYield (x + stride) stride toMinus
544 step _ EnumStop = return Stop
546{-# INLINE_NORMAL enumerateFromThenToIntegralDn #-}
547enumerateFromThenToIntegralDn
548 :: (Monad m, Integral a)
549 => a -> a -> a -> Stream m a
550enumerateFromThenToIntegralDn from next to = Stream step EnumInit
551 where
552 {-# INLINE_LATE step #-}
553 step _ EnumInit =
554 return $ if to > next
555 then if to > from
556 then Stop
557 else Yield from EnumStop
558 else -- from >= next >= to
559 let stride = next - from
560 in Skip $ EnumYield from stride (to - stride)
562 step _ (EnumYield x stride toMinus) =
563 return $
564 if x < toMinus
565 then Yield x EnumStop
566 else Yield x $ EnumYield (x + stride) stride toMinus
568 step _ EnumStop = return Stop
570{-# INLINE_NORMAL enumerateFromThenToIntegral #-}
571enumerateFromThenToIntegral
572 :: (Monad m, Integral a)
573 => a -> a -> a -> Stream m a
574enumerateFromThenToIntegral from next to
575 | next >= from = enumerateFromThenToIntegralUp from next to
576 | otherwise = enumerateFromThenToIntegralDn from next to
578{-# INLINE_NORMAL enumerateFromThenIntegral #-}
579enumerateFromThenIntegral
580 :: (Monad m, Integral a, Bounded a)
581 => a -> a -> Stream m a
582enumerateFromThenIntegral from next =
583 if next > from
584 then enumerateFromThenToIntegralUp from next maxBound
585 else enumerateFromThenToIntegralDn from next minBound
587-- For floating point numbers if the increment is less than the precision then
588-- it just gets lost. Therefore we cannot always increment it correctly by just
589-- repeated addition.
590-- 9007199254740992 + 1 + 1 :: Double => 9.007199254740992e15
591-- 9007199254740992 + 2 :: Double => 9.007199254740994e15
593-- Instead we accumulate the increment counter and compute the increment
594-- every time before adding it to the starting number.
595--
596-- This works for Integrals as well as floating point numbers, but
597-- enumerateFromStepIntegral is faster for integrals.
598{-# INLINE_NORMAL enumerateFromStepNum #-}
599enumerateFromStepNum :: (Monad m, Num a) => a -> a -> Stream m a
600enumerateFromStepNum from stride = Stream step 0
601 where
602 {-# INLINE_LATE step #-}
603 step _ !i = return $ (Yield $! (from + i * stride)) $! (i + 1)
605{-# INLINE_NORMAL numFrom #-}
606numFrom :: (Monad m, Num a) => a -> Stream m a
607numFrom from = enumerateFromStepNum from 1
609{-# INLINE_NORMAL numFromThen #-}
610numFromThen :: (Monad m, Num a) => a -> a -> Stream m a
611numFromThen from next = enumerateFromStepNum from (next - from)
613-- We cannot write a general function for Num. The only way to write code
614-- portable between the two is to use a 'Real' constraint and convert between
615-- Fractional and Integral using fromRational which is horribly slow.
616{-# INLINE_NORMAL enumerateFromToFractional #-}
617enumerateFromToFractional
618 :: (Monad m, Fractional a, Ord a)
619 => a -> a -> Stream m a
620enumerateFromToFractional from to =
621 takeWhile (<= to + 1 / 2) $ enumerateFromStepNum from 1
623{-# INLINE_NORMAL enumerateFromThenToFractional #-}
624enumerateFromThenToFractional
625 :: (Monad m, Fractional a, Ord a)
626 => a -> a -> a -> Stream m a
627enumerateFromThenToFractional from next to =
628 takeWhile predicate $ numFromThen from next
629 where
630 mid = (next - from) / 2
631 predicate | next >= from = (<= to + mid)
632 | otherwise = (>= to + mid)
634-------------------------------------------------------------------------------
635-- Generation by Conversion
636-------------------------------------------------------------------------------
638{-# INLINE_NORMAL fromIndicesM #-}
639fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
640fromIndicesM gen = Stream step 0
641 where
642 {-# INLINE_LATE step #-}
643 step _ i = do
644 x <- gen i
645 return $ Yield x (i + 1)
647{-# INLINE fromIndices #-}
648fromIndices :: Monad m => (Int -> a) -> Stream m a
649fromIndices gen = fromIndicesM (return . gen)
651{-# INLINE_NORMAL generateM #-}
652generateM :: Monad m => Int -> (Int -> m a) -> Stream m a
653generateM n gen = n `seq` Stream step 0
654 where
655 {-# INLINE_LATE step #-}
656 step _ i | i < n = do
657 x <- gen i
658 return $ Yield x (i + 1)
659 | otherwise = return Stop
661{-# INLINE generate #-}
662generate :: Monad m => Int -> (Int -> a) -> Stream m a
663generate n gen = generateM n (return . gen)
665-- XXX we need the MonadAsync constraint because of a rewrite rule.
666-- | Convert a list of monadic actions to a 'Stream'
667{-# INLINE_LATE fromListM #-}
668fromListM :: MonadAsync m => [m a] -> Stream m a
669fromListM = Stream step
670 where
671 {-# INLINE_LATE step #-}
672 step _ (m:ms) = m >>= \x -> return $ Yield x ms
673 step _ [] = return Stop
675{-# INLINE toStreamD #-}
676toStreamD :: (K.IsStream t, Monad m) => t m a -> Stream m a
677toStreamD = fromStreamK . K.toStream
679{-# INLINE_NORMAL fromPrimVar #-}
680fromPrimVar :: (MonadIO m, Prim a) => Var IO a -> Stream m a
681fromPrimVar var = Stream step ()
682 where
683 {-# INLINE_LATE step #-}
684 step _ () = liftIO (readVar var) >>= \x -> return $ Yield x ()
686-------------------------------------------------------------------------------
687-- Generation from SVar
688-------------------------------------------------------------------------------
690data FromSVarState t m a =
691 FromSVarInit
692 | FromSVarRead (SVar t m a)
693 | FromSVarLoop (SVar t m a) [ChildEvent a]
694 | FromSVarDone (SVar t m a)
696{-# INLINE_NORMAL fromSVar #-}
697fromSVar :: (MonadAsync m) => SVar t m a -> Stream m a
698fromSVar svar = Stream step FromSVarInit
699 where
701 {-# INLINE_LATE step #-}
702 step _ FromSVarInit = do
703 ref <- liftIO $ newIORef ()
704 _ <- liftIO $ mkWeakIORef ref hook
705 -- when this copy of svar gets garbage collected "ref" will get
706 -- garbage collected and our GC hook will be called.
707 let sv = svar{svarRef = Just ref}
708 return $ Skip (FromSVarRead sv)
710 where
712 {-# NOINLINE hook #-}
713 hook = do
714 when (svarInspectMode svar) $ do
715 r <- liftIO $ readIORef (svarStopTime (svarStats svar))
716 when (isNothing r) $
717 printSVar svar "SVar Garbage Collected"
718 cleanupSVar svar
719 -- If there are any SVars referenced by this SVar a GC will prompt
720 -- them to be cleaned up quickly.
721 when (svarInspectMode svar) performMajorGC
723 step _ (FromSVarRead sv) = do
724 list <- readOutputQ sv
725 -- Reversing the output is important to guarantee that we process the
726 -- outputs in the same order as they were generated by the constituent
727 -- streams.
728 return $ Skip $ FromSVarLoop sv (Prelude.reverse list)
730 step _ (FromSVarLoop sv []) = do
731 done <- postProcess sv
732 return $ Skip $ if done
733 then (FromSVarDone sv)
734 else (FromSVarRead sv)
736 step _ (FromSVarLoop sv (ev : es)) = do
737 case ev of
738 ChildYield a -> return $ Yield a (FromSVarLoop sv es)
739 ChildStop tid e -> do
740 accountThread sv tid
741 case e of
742 Nothing -> do
743 stop <- shouldStop tid
744 if stop
745 then do
746 liftIO (cleanupSVar sv)
747 return $ Skip (FromSVarDone sv)
748 else return $ Skip (FromSVarLoop sv es)
749 Just ex ->
750 case fromException ex of
751 Just ThreadAbort ->
752 return $ Skip (FromSVarLoop sv es)
753 Nothing -> liftIO (cleanupSVar sv) >> throwM ex
754 where
756 shouldStop tid =
757 case svarStopStyle sv of
758 StopNone -> return False
759 StopAny -> return True
760 StopBy -> do
761 sid <- liftIO $ readIORef (svarStopBy sv)
762 return $ if tid == sid then True else False
764 step _ (FromSVarDone sv) = do
765 when (svarInspectMode sv) $ do
766 t <- liftIO $ getTime Monotonic
767 liftIO $ writeIORef (svarStopTime (svarStats sv)) (Just t)
768 liftIO $ printSVar sv "SVar Done"
769 return Stop
771-------------------------------------------------------------------------------
772-- Process events received by a fold consumer from a stream producer
773-------------------------------------------------------------------------------
775{-# INLINE_NORMAL fromProducer #-}
776fromProducer :: (MonadAsync m) => SVar t m a -> Stream m a
777fromProducer svar = Stream step (FromSVarRead svar)
778 where
780 {-# INLINE_LATE step #-}
781 step _ (FromSVarRead sv) = do
782 list <- readOutputQ sv
783 -- Reversing the output is important to guarantee that we process the
784 -- outputs in the same order as they were generated by the constituent
785 -- streams.
786 return $ Skip $ FromSVarLoop sv (Prelude.reverse list)
788 step _ (FromSVarLoop sv []) = return $ Skip $ FromSVarRead sv
789 step _ (FromSVarLoop sv (ev : es)) = do
790 case ev of
791 ChildYield a -> return $ Yield a (FromSVarLoop sv es)
792 ChildStop tid e -> do
793 accountThread sv tid
794 case e of
795 Nothing -> do
796 sendStopToProducer sv
797 return $ Skip (FromSVarDone sv)
798 Just _ -> error "Bug: fromProducer: received exception"
800 step _ (FromSVarDone sv) = do
801 when (svarInspectMode sv) $ do
802 t <- liftIO $ getTime Monotonic
803 liftIO $ writeIORef (svarStopTime (svarStats sv)) (Just t)
804 liftIO $ printSVar sv "SVar Done"
805 return Stop
807 step _ FromSVarInit = undefined
809-------------------------------------------------------------------------------
810-- Hoisting the inner monad
811-------------------------------------------------------------------------------
813{-# INLINE_NORMAL hoist #-}
814hoist :: Monad n => (forall x. m x -> n x) -> Stream m a -> Stream n a
815hoist f (Stream step state) = (Stream step' state)
816 where
817 {-# INLINE_LATE step' #-}
818 step' gst st = do
819 r <- f $ step (adaptState gst) st
820 return $ case r of
821 Yield x s -> Yield x s
822 Skip s -> Skip s
823 Stop -> Stop
825{-# INLINE generally #-}
826generally :: Monad m => Stream Identity a -> Stream m a
827generally = hoist (return . runIdentity)
829{-# INLINE_NORMAL liftInner #-}
830liftInner :: (Monad m, MonadTrans t, Monad (t m))
831 => Stream m a -> Stream (t m) a
832liftInner (Stream step state) = Stream step' state
833 where
834 {-# INLINE_LATE step' #-}
835 step' gst st = do
836 r <- lift $ step (adaptState gst) st
837 return $ case r of
838 Yield x s -> Yield x s
839 Skip s -> Skip s
840 Stop -> Stop
842{-# INLINE_NORMAL runReaderT #-}
843runReaderT :: Monad m => s -> Stream (ReaderT s m) a -> Stream m a
844runReaderT sval (Stream step state) = Stream step' state
845 where
846 {-# INLINE_LATE step' #-}
847 step' gst st = do
848 r <- Reader.runReaderT (step (adaptState gst) st) sval
849 return $ case r of
850 Yield x s -> Yield x s
851 Skip s -> Skip s
852 Stop -> Stop
854{-# INLINE_NORMAL evalStateT #-}
855evalStateT :: Monad m => s -> Stream (StateT s m) a -> Stream m a
856evalStateT sval (Stream step state) = Stream step' (state, sval)
857 where
858 {-# INLINE_LATE step' #-}
859 step' gst (st, sv) = do
860 (r, sv') <- State.runStateT (step (adaptState gst) st) sv
861 return $ case r of
862 Yield x s -> Yield x (s, sv')
863 Skip s -> Skip (s, sv')
864 Stop -> Stop
866{-# INLINE_NORMAL runStateT #-}
867runStateT :: Monad m => s -> Stream (StateT s m) a -> Stream m (s, a)
868runStateT sval (Stream step state) = Stream step' (state, sval)
869 where
870 {-# INLINE_LATE step' #-}
871 step' gst (st, sv) = do
872 (r, sv') <- State.runStateT (step (adaptState gst) st) sv
873 return $ case r of
874 Yield x s -> Yield (sv', x) (s, sv')
875 Skip s -> Skip (s, sv')
876 Stop -> Stop
878------------------------------------------------------------------------------
879-- Elimination by Folds
880------------------------------------------------------------------------------
882------------------------------------------------------------------------------
883-- Right Folds
884------------------------------------------------------------------------------
886{-# INLINE_NORMAL foldr1 #-}
887foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
888foldr1 f m = do
889 r <- uncons m
890 case r of
891 Nothing -> return Nothing
892 Just (h, t) -> fmap Just (foldr f h t)
894------------------------------------------------------------------------------
895-- Left Folds
896------------------------------------------------------------------------------
898{-# INLINE_NORMAL foldlT #-}
899foldlT :: (Monad m, Monad (s m), MonadTrans s)
900 => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
901foldlT fstep begin (Stream step state) = go SPEC begin state
902 where
903 go !_ acc st = do
904 r <- lift $ step defState st
905 case r of
906 Yield x s -> go SPEC (fstep acc x) s
907 Skip s -> go SPEC acc s
908 Stop -> acc
910-- Note, this is going to have horrible performance, because of the nature of
911-- the stream type (i.e. direct stream vs CPS). Its only for reference, it is
912-- likely be practically unusable.
913{-# INLINE_NORMAL foldlS #-}
914foldlS :: Monad m
915 => (Stream m b -> a -> Stream m b) -> Stream m b -> Stream m a -> Stream m b
916foldlS fstep begin (Stream step state) = Stream step' (Left (state, begin))
917 where
918 step' gst (Left (st, acc)) = do
919 r <- step (adaptState gst) st
920 return $ case r of
921 Yield x s -> Skip (Left (s, fstep acc x))
922 Skip s -> Skip (Left (s, acc))
923 Stop -> Skip (Right acc)
925 step' gst (Right (Stream stp stt)) = do
926 r <- stp (adaptState gst) stt
927 return $ case r of
928 Yield x s -> Yield x (Right (Stream stp s))
929 Skip s -> Skip (Right (Stream stp s))
930 Stop -> Stop
932------------------------------------------------------------------------------
933-- Specialized Folds
934------------------------------------------------------------------------------
936-- | Run a streaming composition, discard the results.
937{-# INLINE_LATE drain #-}
938drain :: Monad m => Stream m a -> m ()
939-- drain = foldrM (\_ xs -> xs) (return ())
940drain (Stream step state) = go SPEC state
941 where
942 go !_ st = do
943 r <- step defState st
944 case r of
945 Yield _ s -> go SPEC s
946 Skip s -> go SPEC s
947 Stop -> return ()
949{-# INLINE_NORMAL null #-}
950null :: Monad m => Stream m a -> m Bool
951null m = foldrM (\_ _ -> return False) (return True) m
953{-# INLINE_NORMAL head #-}
954head :: Monad m => Stream m a -> m (Maybe a)
955head m = foldrM (\x _ -> return (Just x)) (return Nothing) m
957{-# INLINE_NORMAL headElse #-}
958headElse :: Monad m => a -> Stream m a -> m a
959headElse a m = foldrM (\x _ -> return x) (return a) m
961-- Does not fuse, has the same performance as the StreamK version.
962{-# INLINE_NORMAL tail #-}
963tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
964tail (UnStream step state) = go state
965 where
966 go st = do
967 r <- step defState st
968 case r of
969 Yield _ s -> return (Just $ Stream step s)
970 Skip s -> go s
971 Stop -> return Nothing
973-- XXX will it fuse? need custom impl?
974{-# INLINE_NORMAL last #-}
975last :: Monad m => Stream m a -> m (Maybe a)
976last = foldl' (\_ y -> Just y) Nothing
978{-# INLINE_NORMAL elem #-}
979elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
980-- elem e m = foldrM (\x xs -> if x == e then return True else xs) (return False) m
981elem e (Stream step state) = go state
982 where
983 go st = do
984 r <- step defState st
985 case r of
986 Yield x s
987 | x == e -> return True
988 | otherwise -> go s
989 Skip s -> go s
990 Stop -> return False
992{-# INLINE_NORMAL notElem #-}
993notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
994notElem e s = fmap not (elem e s)
996{-# INLINE_NORMAL all #-}
997all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
998-- all p m = foldrM (\x xs -> if p x then xs else return False) (return True) m
999all p (Stream step state) = go state
1000 where
1001 go st = do
1002 r <- step defState st
1003 case r of
1004 Yield x s
1005 | p x -> go s
1006 | otherwise -> return False
1007 Skip s -> go s
1008 Stop -> return True
1010{-# INLINE_NORMAL any #-}
1011any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
1012-- any p m = foldrM (\x xs -> if p x then return True else xs) (return False) m
1013any p (Stream step state) = go state
1014 where
1015 go st = do
1016 r <- step defState st
1017 case r of
1018 Yield x s
1019 | p x -> return True
1020 | otherwise -> go s
1021 Skip s -> go s
1022 Stop -> return False
1024{-# INLINE_NORMAL maximum #-}
1025maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
1026maximum (Stream step state) = go Nothing state
1027 where
1028 go Nothing st = do
1029 r <- step defState st
1030 case r of
1031 Yield x s -> go (Just x) s
1032 Skip s -> go Nothing s
1033 Stop -> return Nothing
1034 go (Just acc) st = do
1035 r <- step defState st
1036 case r of
1037 Yield x s
1038 | acc <= x -> go (Just x) s
1039 | otherwise -> go (Just acc) s
1040 Skip s -> go (Just acc) s
1041 Stop -> return (Just acc)
1043{-# INLINE_NORMAL maximumBy #-}
1044maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
1045maximumBy cmp (Stream step state) = go Nothing state
1046 where
1047 go Nothing st = do
1048 r <- step defState st
1049 case r of
1050 Yield x s -> go (Just x) s
1051 Skip s -> go Nothing s
1052 Stop -> return Nothing
1053 go (Just acc) st = do
1054 r <- step defState st
1055 case r of
1056 Yield x s -> case cmp acc x of
1057 GT -> go (Just acc) s
1058 _ -> go (Just x) s
1059 Skip s -> go (Just acc) s
1060 Stop -> return (Just acc)
1062{-# INLINE_NORMAL minimum #-}
1063minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
1064minimum (Stream step state) = go Nothing state
1065 where
1066 go Nothing st = do
1067 r <- step defState st
1068 case r of
1069 Yield x s -> go (Just x) s
1070 Skip s -> go Nothing s
1071 Stop -> return Nothing
1072 go (Just acc) st = do
1073 r <- step defState st
1074 case r of
1075 Yield x s
1076 | acc <= x -> go (Just acc) s
1077 | otherwise -> go (Just x) s
1078 Skip s -> go (Just acc) s
1079 Stop -> return (Just acc)
1081{-# INLINE_NORMAL minimumBy #-}
1082minimumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
1083minimumBy cmp (Stream step state) = go Nothing state
1084 where
1085 go Nothing st = do
1086 r <- step defState st
1087 case r of
1088 Yield x s -> go (Just x) s
1089 Skip s -> go Nothing s
1090 Stop -> return Nothing
1091 go (Just acc) st = do
1092 r <- step defState st
1093 case r of
1094 Yield x s -> case cmp acc x of
1095 GT -> go (Just x) s
1096 _ -> go (Just acc) s
1097 Skip s -> go (Just acc) s
1098 Stop -> return (Just acc)
1100{-# INLINE_NORMAL (!!) #-}
1101(!!) :: (Monad m) => Stream m a -> Int -> m (Maybe a)
1102(Stream step state) !! i = go i state
1103 where
1104 go n st = do
1105 r <- step defState st
1106 case r of
1107 Yield x s | n < 0 -> return Nothing
1108 | n == 0 -> return $ Just x
1109 | otherwise -> go (n - 1) s
1110 Skip s -> go n s
1111 Stop -> return Nothing
1113{-# INLINE_NORMAL lookup #-}
1114lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
1115lookup e m = foldrM (\(a, b) xs -> if e == a then return (Just b) else xs)
1116 (return Nothing) m
1118{-# INLINE_NORMAL findM #-}
1119findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
1120findM p m = foldrM (\x xs -> p x >>= \r -> if r then return (Just x) else xs)
1121 (return Nothing) m
1123{-# INLINE find #-}
1124find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
1125find p = findM (return . p)
1127{-# INLINE_NORMAL findIndices #-}
1128findIndices :: Monad m => (a -> Bool) -> Stream m a -> Stream m Int
1129findIndices p (Stream step state) = Stream step' (state, 0)
1130 where
1131 {-# INLINE_LATE step' #-}
1132 step' gst (st, i) = i `seq` do
1133 r <- step (adaptState gst) st
1134 return $ case r of
1135 Yield x s -> if p x then Yield i (s, i+1) else Skip (s, i+1)
1136 Skip s -> Skip (s, i)
1137 Stop -> Stop
1139{-# INLINE toListRev #-}
1140toListRev :: Monad m => Stream m a -> m [a]
1141toListRev = foldl' (flip (:)) []
1143-- We can implement reverse as:
1145-- > reverse = foldlS (flip cons) nil
1147-- However, this implementation is unusable because of the horrible performance
1148-- of cons. So we just convert it to a list first and then stream from the
1149-- list.
1151-- XXX Maybe we can use an Array instead of a list here?
1152{-# INLINE_NORMAL reverse #-}
1153reverse :: Monad m => Stream m a -> Stream m a
1154reverse m = Stream step Nothing
1155 where
1156 {-# INLINE_LATE step #-}
1157 step _ Nothing = do
1158 xs <- toListRev m
1159 return $ Skip (Just xs)
1160 step _ (Just (x:xs)) = return $ Yield x (Just xs)
1161 step _ (Just []) = return Stop
1163-- Much faster reverse for Storables
1164{-# INLINE_NORMAL reverse' #-}
1165reverse' :: forall m a. (MonadIO m, Storable a) => Stream m a -> Stream m a
1167-- This commented implementation copies the whole stream into one single array
1168-- and then streams from that array, this is 3-4x faster than the chunked code
1169-- that follows. Though this could be problematic due to unbounded large
1170-- allocations. We need to figure out why the chunked code is slower and if we
1171-- can optimize the chunked code to work as fast as this one. It may be a
1172-- fusion issue?
1173import Foreign.ForeignPtr (touchForeignPtr)
1174import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
1175import Foreign.Ptr (Ptr, plusPtr)
1176reverse' m = Stream step Nothing
1177 where
1178 {-# INLINE_LATE step #-}
1179 step _ Nothing = do
1180 arr <- A.fromStreamD m
1181 let p = aEnd arr `plusPtr` negate (sizeOf (undefined :: a))
1182 return $ Skip $ Just (aStart arr, p)
1184 step _ (Just (start, p)) | p < unsafeForeignPtrToPtr start = return Stop
1186 step _ (Just (start, p)) = do
1187 let !x = A.unsafeInlineIO $ do
1188 r <- peek p
1189 touchForeignPtr start
1190 return r
1191 next = p `plusPtr` negate (sizeOf (undefined :: a))
1192 return $ Yield x (Just (start, next))
1194reverse' m =
1195 A.flattenArraysRev
1196 $ fromStreamK
1197 $ K.reverse
1198 $ toStreamK
1199 $ A.fromStreamDArraysOf A.defaultChunkSize m
1202------------------------------------------------------------------------------
1203-- Grouping/Splitting
1204------------------------------------------------------------------------------
1206{-# INLINE_NORMAL splitSuffixBy' #-}
1207splitSuffixBy' :: Monad m
1208 => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1209splitSuffixBy' predicate f (Stream step state) =
1210 Stream (stepOuter f) (Just state)
1212 where
1214 {-# INLINE_LATE stepOuter #-}
1215 stepOuter (Fold fstep initial done) gst (Just st) = do
1216 res <- step (adaptState gst) st
1217 case res of
1218 Yield x s -> do
1219 acc <- initial
1220 acc' <- fstep acc x
1221 if (predicate x)
1222 then done acc' >>= \val -> return $ Yield val (Just s)
1223 else go SPEC s acc'
1225 Skip s -> return $ Skip $ Just s
1226 Stop -> return Stop
1228 where
1230 go !_ stt !acc = do
1231 res <- step (adaptState gst) stt
1232 case res of
1233 Yield x s -> do
1234 acc' <- fstep acc x
1235 if (predicate x)
1236 then done acc' >>= \val -> return $ Yield val (Just s)
1237 else go SPEC s acc'
1238 Skip s -> go SPEC s acc
1239 Stop -> done acc >>= \val -> return $ Yield val Nothing
1241 stepOuter _ _ Nothing = return Stop
1243{-# INLINE_NORMAL groupsBy #-}
1244groupsBy :: Monad m
1245 => (a -> a -> Bool)
1246 -> Fold m a b
1247 -> Stream m a
1248 -> Stream m b
1249groupsBy cmp f (Stream step state) = Stream (stepOuter f) (Just state, Nothing)
1251 where
1253 {-# INLINE_LATE stepOuter #-}
1254 stepOuter (Fold fstep initial done) gst (Just st, Nothing) = do
1255 res <- step (adaptState gst) st
1256 case res of
1257 Yield x s -> do
1258 acc <- initial
1259 acc' <- fstep acc x
1260 go SPEC x s acc'
1262 Skip s -> return $ Skip $ (Just s, Nothing)
1263 Stop -> return Stop
1265 where
1267 go !_ prev stt !acc = do
1268 res <- step (adaptState gst) stt
1269 case res of
1270 Yield x s -> do
1271 if cmp x prev
1272 then do
1273 acc' <- fstep acc x
1274 go SPEC prev s acc'
1275 else done acc >>= \r -> return $ Yield r (Just s, Just x)
1276 Skip s -> go SPEC prev s acc
1277 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1279 stepOuter (Fold fstep initial done) gst (Just st, Just prev) = do
1280 acc <- initial
1281 acc' <- fstep acc prev
1282 go SPEC st acc'
1284 where
1286 -- XXX code duplicated from the previous equation
1287 go !_ stt !acc = do
1288 res <- step (adaptState gst) stt
1289 case res of
1290 Yield x s -> do
1291 if cmp x prev
1292 then do
1293 acc' <- fstep acc x
1294 go SPEC s acc'
1295 else done acc >>= \r -> return $ Yield r (Just s, Just x)
1296 Skip s -> go SPEC s acc
1297 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1299 stepOuter _ _ (Nothing,_) = return Stop
1301{-# INLINE_NORMAL groupsRollingBy #-}
1302groupsRollingBy :: Monad m
1303 => (a -> a -> Bool)
1304 -> Fold m a b
1305 -> Stream m a
1306 -> Stream m b
1307groupsRollingBy cmp f (Stream step state) =
1308 Stream (stepOuter f) (Just state, Nothing)
1309 where
1311 {-# INLINE_LATE stepOuter #-}
1312 stepOuter (Fold fstep initial done) gst (Just st, Nothing) = do
1313 res <- step (adaptState gst) st
1314 case res of
1315 Yield x s -> do
1316 acc <- initial
1317 acc' <- fstep acc x
1318 go SPEC x s acc'
1320 Skip s -> return $ Skip $ (Just s, Nothing)
1321 Stop -> return Stop
1323 where
1324 go !_ prev stt !acc = do
1325 res <- step (adaptState gst) stt
1326 case res of
1327 Yield x s -> do
1328 if cmp prev x
1329 then do
1330 acc' <- fstep acc x
1331 go SPEC x s acc'
1332 else
1333 done acc >>= \r -> return $ Yield r (Just s, Just x)
1334 Skip s -> go SPEC prev s acc
1335 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1337 stepOuter (Fold fstep initial done) gst (Just st, Just prev') = do
1338 acc <- initial
1339 acc' <- fstep acc prev'
1340 go SPEC prev' st acc'
1342 where
1343 go !_ prevv stt !acc = do
1344 res <- step (adaptState gst) stt
1345 case res of
1346 Yield x s -> do
1347 if cmp prevv x
1348 then do
1349 acc' <- fstep acc x
1350 go SPEC x s acc'
1351 else done acc >>= \r -> return $ Yield r (Just s, Just x)
1352 Skip s -> go SPEC prevv s acc
1353 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1355 stepOuter _ _ (Nothing, _) = return Stop
1357{-# INLINE_NORMAL splitBy #-}
1358splitBy :: Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1359splitBy predicate f (Stream step state) = Stream (step' f) (Just state)
1361 where
1363 {-# INLINE_LATE step' #-}
1364 step' (Fold fstep initial done) gst (Just st) = initial >>= go SPEC st
1366 where
1368 go !_ stt !acc = do
1369 res <- step (adaptState gst) stt
1370 case res of
1371 Yield x s -> do
1372 if predicate x
1373 then done acc >>= \r -> return $ Yield r (Just s)
1374 else do
1375 acc' <- fstep acc x
1376 go SPEC s acc'
1377 Skip s -> go SPEC s acc
1378 Stop -> done acc >>= \r -> return $ Yield r Nothing
1380 step' _ _ Nothing = return Stop
1382-- XXX requires -funfolding-use-threshold=150 in lines-unlines benchmark
1383{-# INLINE_NORMAL splitSuffixBy #-}
1384splitSuffixBy :: Monad m
1385 => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1386splitSuffixBy predicate f (Stream step state) = Stream (step' f) (Just state)
1388 where
1390 {-# INLINE_LATE step' #-}
1391 step' (Fold fstep initial done) gst (Just st) = do
1392 res <- step (adaptState gst) st
1393 case res of
1394 Yield x s -> do
1395 acc <- initial
1396 if predicate x
1397 then done acc >>= \val -> return $ Yield val (Just s)
1398 else do
1399 acc' <- fstep acc x
1400 go SPEC s acc'
1402 Skip s -> return $ Skip $ Just s
1403 Stop -> return Stop
1405 where
1407 go !_ stt !acc = do
1408 res <- step (adaptState gst) stt
1409 case res of
1410 Yield x s -> do
1411 if predicate x
1412 then done acc >>= \r -> return $ Yield r (Just s)
1413 else do
1414 acc' <- fstep acc x
1415 go SPEC s acc'
1416 Skip s -> go SPEC s acc
1417 Stop -> done acc >>= \r -> return $ Yield r Nothing
1419 step' _ _ Nothing = return Stop
1421{-# INLINE_NORMAL wordsBy #-}
1422wordsBy :: Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1423wordsBy predicate f (Stream step state) = Stream (stepOuter f) (Just state)
1425 where
1427 {-# INLINE_LATE stepOuter #-}
1428 stepOuter (Fold fstep initial done) gst (Just st) = do
1429 res <- step (adaptState gst) st
1430 case res of
1431 Yield x s -> do
1432 if predicate x
1433 then return $ Skip (Just s)
1434 else do
1435 acc <- initial
1436 acc' <- fstep acc x
1437 go SPEC s acc'
1439 Skip s -> return $ Skip $ Just s
1440 Stop -> return Stop
1442 where
1444 go !_ stt !acc = do
1445 res <- step (adaptState gst) stt
1446 case res of
1447 Yield x s -> do
1448 if predicate x
1449 then done acc >>= \r -> return $ Yield r (Just s)
1450 else do
1451 acc' <- fstep acc x
1452 go SPEC s acc'
1453 Skip s -> go SPEC s acc
1454 Stop -> done acc >>= \r -> return $ Yield r Nothing
1456 stepOuter _ _ Nothing = return Stop
1458-- String search algorithms:
1459-- http://www-igm.univ-mlv.fr/~lecroq/string/index.html
1462-- TODO can we unify the splitting operations using a splitting configuration
1463-- like in the split package.
1465data SplitStyle = Infix | Suffix | Prefix deriving (Eq, Show)
1467data SplitOptions = SplitOptions
1468 { style :: SplitStyle
1469 , withSep :: Bool -- ^ keep the separators in output
1470 -- , compact :: Bool -- ^ treat multiple consecutive separators as one
1471 -- , trimHead :: Bool -- ^ drop blank at head
1472 -- , trimTail :: Bool -- ^ drop blank at tail
1476data SplitOnState s a =
1477 GO_START
1478 | GO_EMPTY_PAT s
1479 | GO_SINGLE_PAT s a
1480 | GO_SHORT_PAT s
1481 | GO_KARP_RABIN s !(RB.Ring a) !(Ptr a)
1482 | GO_DONE
1484{-# INLINE_NORMAL splitOn #-}
1485splitOn
1486 :: forall m a b. (MonadIO m, Storable a, Enum a, Eq a)
1487 => Array a
1488 -> Fold m a b
1489 -> Stream m a
1490 -> Stream m b
1491splitOn patArr@Array{..} (Fold fstep initial done) (Stream step state) =
1492 Stream stepOuter GO_START
1494 where
1496 patLen = A.length patArr
1497 maxIndex = patLen - 1
1498 elemBits = sizeOf (undefined :: a) * 8
1500 {-# INLINE_LATE stepOuter #-}
1501 stepOuter _ GO_START =
1502 if patLen == 0
1503 then return $ Skip $ GO_EMPTY_PAT state
1504 else if patLen == 1
1505 then do
1506 r <- liftIO $ (A.unsafeIndexIO patArr 0)
1507 return $ Skip $ GO_SINGLE_PAT state r
1508 else if sizeOf (undefined :: a) * patLen
1509 <= sizeOf (undefined :: Word)
1510 then return $ Skip $ GO_SHORT_PAT state
1511 else do
1512 (rb, rhead) <- liftIO $ RB.new patLen
1513 return $ Skip $ GO_KARP_RABIN state rb rhead
1515 stepOuter gst (GO_SINGLE_PAT stt pat) = initial >>= go SPEC stt
1517 where
1519 go !_ st !acc = do
1520 res <- step (adaptState gst) st
1521 case res of
1522 Yield x s -> do
1523 if pat == x
1524 then do
1525 r <- done acc
1526 return $ Yield r (GO_SINGLE_PAT s pat)
1527 else fstep acc x >>= go SPEC s
1528 Skip s -> go SPEC s acc
1529 Stop -> done acc >>= \r -> return $ Yield r GO_DONE
1531 stepOuter gst (GO_SHORT_PAT stt) = initial >>= go0 SPEC 0 (0 :: Word) stt
1533 where
1535 mask :: Word
1536 mask = (1 `shiftL` (elemBits * patLen)) - 1
1538 addToWord wrd a = (wrd `shiftL` elemBits) .|. fromIntegral (fromEnum a)
1540 patWord :: Word
1541 patWord = mask .&. A.foldl' addToWord 0 patArr
1543 go0 !_ !idx wrd st !acc = do
1544 res <- step (adaptState gst) st
1545 case res of
1546 Yield x s -> do
1547 let wrd' = addToWord wrd x
1548 if idx == maxIndex
1549 then do
1550 if wrd' .&. mask == patWord
1551 then do
1552 r <- done acc
1553 return $ Yield r (GO_SHORT_PAT s)
1554 else go1 SPEC wrd' s acc
1555 else go0 SPEC (idx + 1) wrd' s acc
1556 Skip s -> go0 SPEC idx wrd s acc
1557 Stop -> do
1558 acc' <- if idx /= 0
1559 then go2 wrd idx acc
1560 else return acc
1561 done acc' >>= \r -> return $ Yield r GO_DONE
1563 {-# INLINE go1 #-}
1564 go1 !_ wrd st !acc = do
1565 res <- step (adaptState gst) st
1566 case res of
1567 Yield x s -> do
1568 let wrd' = addToWord wrd x
1569 old = (mask .&. wrd) `shiftR` (elemBits * (patLen - 1))
1570 acc' <- fstep acc (toEnum $ fromIntegral old)
1571 if wrd' .&. mask == patWord
1572 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1573 else go1 SPEC wrd' s acc'
1574 Skip s -> go1 SPEC wrd s acc
1575 Stop -> do
1576 acc' <- go2 wrd patLen acc
1577 done acc' >>= \r -> return $ Yield r GO_DONE
1579 go2 !wrd !n !acc | n > 0 = do
1580 let old = (mask .&. wrd) `shiftR` (elemBits * (n - 1))
1581 fstep acc (toEnum $ fromIntegral old) >>= go2 wrd (n - 1)
1582 go2 _ _ acc = return acc
1584 stepOuter gst (GO_KARP_RABIN stt rb rhead) = do
1585 initial >>= go0 SPEC 0 rhead stt
1587 where
1589 k = 2891336453 :: Word32
1590 coeff = k ^ patLen
1591 addCksum cksum a = cksum * k + fromIntegral (fromEnum a)
1592 deltaCksum cksum old new =
1593 addCksum cksum new - coeff * fromIntegral (fromEnum old)
1595 -- XXX shall we use a random starting hash or 1 instead of 0?
1596 patHash = A.foldl' addCksum 0 patArr
1598 -- rh == ringHead
1599 go0 !_ !idx !rh st !acc = do
1600 res <- step (adaptState gst) st
1601 case res of
1602 Yield x s -> do
1603 rh' <- liftIO $ RB.unsafeInsert rb rh x
1604 if idx == maxIndex
1605 then do
1606 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1607 let !ringHash = fold addCksum 0 rb
1608 if ringHash == patHash
1609 then go2 SPEC ringHash rh' s acc
1610 else go1 SPEC ringHash rh' s acc
1611 else go0 SPEC (idx + 1) rh' s acc
1612 Skip s -> go0 SPEC idx rh s acc
1613 Stop -> do
1614 !acc' <- if idx /= 0
1615 then RB.unsafeFoldRingM rh fstep acc rb
1616 else return acc
1617 done acc' >>= \r -> return $ Yield r GO_DONE
1619 -- XXX Theoretically this code can do 4 times faster if GHC generates
1620 -- optimal code. If we use just "(cksum' == patHash)" condition it goes
1621 -- 4x faster, as soon as we add the "RB.unsafeEqArray rb v" condition
1622 -- the generated code changes drastically and becomes 4x slower. Need
1623 -- to investigate what is going on with GHC.
1624 {-# INLINE go1 #-}
1625 go1 !_ !cksum !rh st !acc = do
1626 res <- step (adaptState gst) st
1627 case res of
1628 Yield x s -> do
1629 old <- liftIO $ peek rh
1630 let cksum' = deltaCksum cksum old x
1631 acc' <- fstep acc old
1633 if (cksum' == patHash)
1634 then do
1635 rh' <- liftIO (RB.unsafeInsert rb rh x)
1636 go2 SPEC cksum' rh' s acc'
1637 else do
1638 rh' <- liftIO (RB.unsafeInsert rb rh x)
1639 go1 SPEC cksum' rh' s acc'
1640 Skip s -> go1 SPEC cksum rh s acc
1641 Stop -> do
1642 acc' <- RB.unsafeFoldRingFullM rh fstep acc rb
1643 done acc' >>= \r -> return $ Yield r GO_DONE
1645 go2 !_ !cksum' !rh' s !acc' = do
1646 if RB.unsafeEqArray rb rh' patArr
1647 then do
1648 r <- done acc'
1649 return $ Yield r (GO_KARP_RABIN s rb rhead)
1650 else go1 SPEC cksum' rh' s acc'
1652 stepOuter gst (GO_EMPTY_PAT st) = do
1653 res <- step (adaptState gst) st
1654 case res of
1655 Yield x s -> do
1656 acc <- initial
1657 acc' <- fstep acc x
1658 done acc' >>= \r -> return $ Yield r (GO_EMPTY_PAT s)
1659 Skip s -> return $ Skip (GO_EMPTY_PAT s)
1660 Stop -> return Stop
1662 stepOuter _ GO_DONE = return Stop
1664{-# INLINE_NORMAL splitSuffixOn #-}
1665splitSuffixOn
1666 :: forall m a b. (MonadIO m, Storable a, Enum a, Eq a)
1667 => Bool
1668 -> Array a
1669 -> Fold m a b
1670 -> Stream m a
1671 -> Stream m b
1672splitSuffixOn withSep patArr@Array{..} (Fold fstep initial done)
1673 (Stream step state) =
1674 Stream stepOuter GO_START
1676 where
1678 patLen = A.length patArr
1679 maxIndex = patLen - 1
1680 elemBits = sizeOf (undefined :: a) * 8
1682 {-# INLINE_LATE stepOuter #-}
1683 stepOuter _ GO_START =
1684 if patLen == 0
1685 then return $ Skip $ GO_EMPTY_PAT state
1686 else if patLen == 1
1687 then do
1688 r <- liftIO $ (A.unsafeIndexIO patArr 0)
1689 return $ Skip $ GO_SINGLE_PAT state r
1690 else if sizeOf (undefined :: a) * patLen
1691 <= sizeOf (undefined :: Word)
1692 then return $ Skip $ GO_SHORT_PAT state
1693 else do
1694 (rb, rhead) <- liftIO $ RB.new patLen
1695 return $ Skip $ GO_KARP_RABIN state rb rhead
1697 stepOuter gst (GO_SINGLE_PAT stt pat) = do
1698 -- This first part is the only difference between splitOn and
1699 -- splitSuffixOn.
1700 -- If the last element is a separator do not issue a blank segment.
1701 res <- step (adaptState gst) stt
1702 case res of
1703 Yield x s -> do
1704 acc <- initial
1705 if pat == x
1706 then do
1707 acc' <- if withSep then fstep acc x else return acc
1708 done acc' >>= \r -> return $ Yield r (GO_SINGLE_PAT s pat)
1709 else fstep acc x >>= go SPEC s
1710 Skip s -> return $ Skip $ (GO_SINGLE_PAT s pat)
1711 Stop -> return Stop
1713 where
1715 -- This is identical for splitOn and splitSuffixOn
1716 go !_ st !acc = do
1717 res <- step (adaptState gst) st
1718 case res of
1719 Yield x s -> do
1720 if pat == x
1721 then do
1722 acc' <- if withSep then fstep acc x else return acc
1723 r <- done acc'
1724 return $ Yield r (GO_SINGLE_PAT s pat)
1725 else fstep acc x >>= go SPEC s
1726 Skip s -> go SPEC s acc
1727 Stop -> done acc >>= \r -> return $ Yield r GO_DONE
1729 stepOuter gst (GO_SHORT_PAT stt) = do
1731 -- Call "initial" only if the stream yields an element, otherwise we
1732 -- may call "initial" but never yield anything. initial may produce a
1733 -- side effect, therefore we will end up doing and discard a side
1734 -- effect.
1736 let idx = 0
1737 let wrd = 0
1738 res <- step (adaptState gst) stt
1739 case res of
1740 Yield x s -> do
1741 acc <- initial
1742 let wrd' = addToWord wrd x
1743 acc' <- if withSep then fstep acc x else return acc
1744 if idx == maxIndex
1745 then do
1746 if wrd' .&. mask == patWord
1747 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1748 else go0 SPEC (idx + 1) wrd' s acc'
1749 else go0 SPEC (idx + 1) wrd' s acc'
1750 Skip s -> return $ Skip (GO_SHORT_PAT s)
1751 Stop -> return Stop
1753 where
1755 mask :: Word
1756 mask = (1 `shiftL` (elemBits * patLen)) - 1
1758 addToWord wrd a = (wrd `shiftL` elemBits) .|. fromIntegral (fromEnum a)
1760 patWord :: Word
1761 patWord = mask .&. A.foldl' addToWord 0 patArr
1763 go0 !_ !idx wrd st !acc = do
1764 res <- step (adaptState gst) st
1765 case res of
1766 Yield x s -> do
1767 let wrd' = addToWord wrd x
1768 acc' <- if withSep then fstep acc x else return acc
1769 if idx == maxIndex
1770 then do
1771 if wrd' .&. mask == patWord
1772 then do
1773 r <- done acc'
1774 return $ Yield r (GO_SHORT_PAT s)
1775 else go1 SPEC wrd' s acc'
1776 else go0 SPEC (idx + 1) wrd' s acc'
1777 Skip s -> go0 SPEC idx wrd s acc
1778 Stop -> do
1779 if (idx == maxIndex) && (wrd .&. mask == patWord)
1780 then return Stop
1781 else do
1782 acc' <- if idx /= 0 && not withSep
1783 then go2 wrd idx acc
1784 else return acc
1785 done acc' >>= \r -> return $ Yield r GO_DONE
1787 {-# INLINE go1 #-}
1788 go1 !_ wrd st !acc = do
1789 res <- step (adaptState gst) st
1790 case res of
1791 Yield x s -> do
1792 let wrd' = addToWord wrd x
1793 old = (mask .&. wrd) `shiftR` (elemBits * (patLen - 1))
1794 acc' <- if withSep
1795 then fstep acc x
1796 else fstep acc (toEnum $ fromIntegral old)
1797 if wrd' .&. mask == patWord
1798 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1799 else go1 SPEC wrd' s acc'
1800 Skip s -> go1 SPEC wrd s acc
1801 Stop ->
1802 -- If the last sequence is a separator do not issue a blank
1803 -- segment.
1804 if wrd .&. mask == patWord
1805 then return Stop
1806 else do
1807 acc' <- if withSep
1808 then return acc
1809 else go2 wrd patLen acc
1810 done acc' >>= \r -> return $ Yield r GO_DONE
1812 go2 !wrd !n !acc | n > 0 = do
1813 let old = (mask .&. wrd) `shiftR` (elemBits * (n - 1))
1814 fstep acc (toEnum $ fromIntegral old) >>= go2 wrd (n - 1)
1815 go2 _ _ acc = return acc
1817 stepOuter gst (GO_KARP_RABIN stt rb rhead) = do
1818 let idx = 0
1819 res <- step (adaptState gst) stt
1820 case res of
1821 Yield x s -> do
1822 acc <- initial
1823 acc' <- if withSep then fstep acc x else return acc
1824 rh' <- liftIO (RB.unsafeInsert rb rhead x)
1825 if idx == maxIndex
1826 then do
1827 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1828 let !ringHash = fold addCksum 0 rb
1829 if ringHash == patHash
1830 then go2 SPEC ringHash rh' s acc'
1831 else go0 SPEC (idx + 1) rh' s acc'
1832 else go0 SPEC (idx + 1) rh' s acc'
1833 Skip s -> return $ Skip (GO_KARP_RABIN s rb rhead)
1834 Stop -> return Stop
1836 where
1838 k = 2891336453 :: Word32
1839 coeff = k ^ patLen
1840 addCksum cksum a = cksum * k + fromIntegral (fromEnum a)
1841 deltaCksum cksum old new =
1842 addCksum cksum new - coeff * fromIntegral (fromEnum old)
1844 -- XXX shall we use a random starting hash or 1 instead of 0?
1845 patHash = A.foldl' addCksum 0 patArr
1847 -- rh == ringHead
1848 go0 !_ !idx !rh st !acc = do
1849 res <- step (adaptState gst) st
1850 case res of
1851 Yield x s -> do
1852 acc' <- if withSep then fstep acc x else return acc
1853 rh' <- liftIO (RB.unsafeInsert rb rh x)
1854 if idx == maxIndex
1855 then do
1856 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1857 let !ringHash = fold addCksum 0 rb
1858 if ringHash == patHash
1859 then go2 SPEC ringHash rh' s acc'
1860 else go1 SPEC ringHash rh' s acc'
1861 else go0 SPEC (idx + 1) rh' s acc'
1862 Skip s -> go0 SPEC idx rh s acc
1863 Stop -> do
1864 -- do not issue a blank segment when we end at pattern
1865 if (idx == maxIndex) && RB.unsafeEqArray rb rh patArr
1866 then return Stop
1867 else do
1868 !acc' <- if idx /= 0 && not withSep
1869 then RB.unsafeFoldRingM rh fstep acc rb
1870 else return acc
1871 done acc' >>= \r -> return $ Yield r GO_DONE
1873 -- XXX Theoretically this code can do 4 times faster if GHC generates
1874 -- optimal code. If we use just "(cksum' == patHash)" condition it goes
1875 -- 4x faster, as soon as we add the "RB.unsafeEqArray rb v" condition
1876 -- the generated code changes drastically and becomes 4x slower. Need
1877 -- to investigate what is going on with GHC.
1878 {-# INLINE go1 #-}
1879 go1 !_ !cksum !rh st !acc = do
1880 res <- step (adaptState gst) st
1881 case res of
1882 Yield x s -> do
1883 old <- liftIO $ peek rh
1884 let cksum' = deltaCksum cksum old x
1885 acc' <- if withSep
1886 then fstep acc x
1887 else fstep acc old
1889 if (cksum' == patHash)
1890 then do
1891 rh' <- liftIO (RB.unsafeInsert rb rh x)
1892 go2 SPEC cksum' rh' s acc'
1893 else do
1894 rh' <- liftIO (RB.unsafeInsert rb rh x)
1895 go1 SPEC cksum' rh' s acc'
1896 Skip s -> go1 SPEC cksum rh s acc
1897 Stop -> do
1898 if RB.unsafeEqArray rb rh patArr
1899 then return Stop
1900 else do
1901 acc' <- if withSep
1902 then return acc
1903 else RB.unsafeFoldRingFullM rh fstep acc rb
1904 done acc' >>= \r -> return $ Yield r GO_DONE
1906 go2 !_ !cksum' !rh' s !acc' = do
1907 if RB.unsafeEqArray rb rh' patArr
1908 then do
1909 r <- done acc'
1910 return $ Yield r (GO_KARP_RABIN s rb rhead)
1911 else go1 SPEC cksum' rh' s acc'
1913 stepOuter gst (GO_EMPTY_PAT st) = do
1914 res <- step (adaptState gst) st
1915 case res of
1916 Yield x s -> do
1917 acc <- initial
1918 acc' <- fstep acc x
1919 done acc' >>= \r -> return $ Yield r (GO_EMPTY_PAT s)
1920 Skip s -> return $ Skip (GO_EMPTY_PAT s)
1921 Stop -> return Stop
1923 stepOuter _ GO_DONE = return Stop
1925data SplitState s arr
1926 = SplitInitial s
1927 | SplitBuffering s arr
1928 | SplitSplitting s arr
1929 | SplitYielding arr (SplitState s arr)
1930 | SplitFinishing
1932-- XXX An alternative approach would be to use a partial fold (Fold m a b) to
1933-- split using a splitBy like combinator. The Fold would consume upto the
1934-- separator and return any leftover which can then be fed to the next fold.
1936-- We can revisit this once we have partial folds/parsers.
1938-- | Performs infix separator style splitting.
1939{-# INLINE_NORMAL splitInnerBy #-}
1940splitInnerBy
1941 :: Monad m
1942 => (f a -> m (f a, Maybe (f a))) -- splitter
1943 -> (f a -> f a -> m (f a)) -- joiner
1944 -> Stream m (f a)
1945 -> Stream m (f a)
1946splitInnerBy splitter joiner (Stream step1 state1) =
1947 (Stream step (SplitInitial state1))
1949 where
1951 {-# INLINE_LATE step #-}
1952 step gst (SplitInitial st) = do
1953 r <- step1 gst st
1954 case r of
1955 Yield x s -> do
1956 (x1, mx2) <- splitter x
1957 return $ case mx2 of
1958 Nothing -> Skip (SplitBuffering s x1)
1959 Just x2 -> Skip (SplitYielding x1 (SplitSplitting s x2))
1960 Skip s -> return $ Skip (SplitInitial s)
1961 Stop -> return $ Stop
1963 step gst (SplitBuffering st buf) = do
1964 r <- step1 gst st
1965 case r of
1966 Yield x s -> do
1967 (x1, mx2) <- splitter x
1968 buf' <- joiner buf x1
1969 return $ case mx2 of
1970 Nothing -> Skip (SplitBuffering s buf')
1971 Just x2 -> Skip (SplitYielding buf' (SplitSplitting s x2))
1972 Skip s -> return $ Skip (SplitBuffering s buf)
1973 Stop -> return $ Skip (SplitYielding buf SplitFinishing)
1975 step _ (SplitSplitting st buf) = do
1976 (x1, mx2) <- splitter buf
1977 return $ case mx2 of
1978 Nothing -> Skip $ SplitBuffering st x1
1979 Just x2 -> Skip $ SplitYielding x1 (SplitSplitting st x2)
1981 step _ (SplitYielding x next) = return $ Yield x next
1982 step _ SplitFinishing = return $ Stop
1984-- | Performs infix separator style splitting.
1985{-# INLINE_NORMAL splitInnerBySuffix #-}
1986splitInnerBySuffix
1987 :: (Monad m, Eq (f a), Monoid (f a))
1988 => (f a -> m (f a, Maybe (f a))) -- splitter
1989 -> (f a -> f a -> m (f a)) -- joiner
1990 -> Stream m (f a)
1991 -> Stream m (f a)
1992splitInnerBySuffix splitter joiner (Stream step1 state1) =
1993 (Stream step (SplitInitial state1))
1995 where
1997 {-# INLINE_LATE step #-}
1998 step gst (SplitInitial st) = do
1999 r <- step1 gst st
2000 case r of
2001 Yield x s -> do
2002 (x1, mx2) <- splitter x
2003 return $ case mx2 of
2004 Nothing -> Skip (SplitBuffering s x1)
2005 Just x2 -> Skip (SplitYielding x1 (SplitSplitting s x2))
2006 Skip s -> return $ Skip (SplitInitial s)
2007 Stop -> return $ Stop
2009 step gst (SplitBuffering st buf) = do
2010 r <- step1 gst st
2011 case r of
2012 Yield x s -> do
2013 (x1, mx2) <- splitter x
2014 buf' <- joiner buf x1
2015 return $ case mx2 of
2016 Nothing -> Skip (SplitBuffering s buf')
2017 Just x2 -> Skip (SplitYielding buf' (SplitSplitting s x2))
2018 Skip s -> return $ Skip (SplitBuffering s buf)
2019 Stop -> return $
2020 if buf == mempty
2021 then Stop
2022 else Skip (SplitYielding buf SplitFinishing)
2024 step _ (SplitSplitting st buf) = do
2025 (x1, mx2) <- splitter buf
2026 return $ case mx2 of
2027 Nothing -> Skip $ SplitBuffering st x1
2028 Just x2 -> Skip $ SplitYielding x1 (SplitSplitting st x2)
2030 step _ (SplitYielding x next) = return $ Yield x next
2031 step _ SplitFinishing = return $ Stop
2033------------------------------------------------------------------------------
2034-- Substreams
2035------------------------------------------------------------------------------
2037{-# INLINE_NORMAL isPrefixOf #-}
2038isPrefixOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
2039isPrefixOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
2040 where
2041 go (sa, sb, Nothing) = do
2042 r <- stepa defState sa
2043 case r of
2044 Yield x sa' -> go (sa', sb, Just x)
2045 Skip sa' -> go (sa', sb, Nothing)
2046 Stop -> return True
2048 go (sa, sb, Just x) = do
2049 r <- stepb defState sb
2050 case r of
2051 Yield y sb' ->
2052 if x == y
2053 then go (sa, sb', Nothing)
2054 else return False
2055 Skip sb' -> go (sa, sb', Just x)
2056 Stop -> return False
2058{-# INLINE_NORMAL isSubsequenceOf #-}
2059isSubsequenceOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
2060isSubsequenceOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
2061 where
2062 go (sa, sb, Nothing) = do
2063 r <- stepa defState sa
2064 case r of
2065 Yield x sa' -> go (sa', sb, Just x)
2066 Skip sa' -> go (sa', sb, Nothing)
2067 Stop -> return True
2069 go (sa, sb, Just x) = do
2070 r <- stepb defState sb
2071 case r of
2072 Yield y sb' ->
2073 if x == y
2074 then go (sa, sb', Nothing)
2075 else go (sa, sb', Just x)
2076 Skip sb' -> go (sa, sb', Just x)
2077 Stop -> return False
2079{-# INLINE_NORMAL stripPrefix #-}
2080stripPrefix
2081 :: (Eq a, Monad m)
2082 => Stream m a -> Stream m a -> m (Maybe (Stream m a))
2083stripPrefix (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
2084 where
2085 go (sa, sb, Nothing) = do
2086 r <- stepa defState sa
2087 case r of
2088 Yield x sa' -> go (sa', sb, Just x)
2089 Skip sa' -> go (sa', sb, Nothing)
2090 Stop -> return $ Just (Stream stepb sb)
2092 go (sa, sb, Just x) = do
2093 r <- stepb defState sb
2094 case r of
2095 Yield y sb' ->
2096 if x == y
2097 then go (sa, sb', Nothing)
2098 else return Nothing
2099 Skip sb' -> go (sa, sb', Just x)
2100 Stop -> return Nothing
2102------------------------------------------------------------------------------
2103-- Map and Fold
2104------------------------------------------------------------------------------
2106-- | Execute a monadic action for each element of the 'Stream'
2107{-# INLINE_NORMAL mapM_ #-}
2108mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
2109mapM_ m = drain . mapM m
2111-------------------------------------------------------------------------------
2112-- Stream transformations using Unfolds
2113-------------------------------------------------------------------------------
2115-- Define a unique structure to use in inspection testing
2116data ConcatMapUState o i =
2117 ConcatMapUOuter o
2118 | ConcatMapUInner o i
2120-- | @concatMapU unfold stream@ uses @unfold@ to map the input stream elements
2121-- to streams and then flattens the generated streams into a single output
2122-- stream.
2124-- This is like 'concatMap' but uses an unfold with an explicit state to
2125-- generate the stream instead of a 'Stream' type generator. This allows better
2126-- optimization via fusion. This can be many times more efficient than
2127-- 'concatMap'.
2129{-# INLINE_NORMAL concatMapU #-}
2130concatMapU :: Monad m => Unfold m a b -> Stream m a -> Stream m b
2131concatMapU (Unfold istep inject) (Stream ostep ost) =
2132 Stream step (ConcatMapUOuter ost)
2133 where
2134 {-# INLINE_LATE step #-}
2135 step gst (ConcatMapUOuter o) = do
2136 r <- ostep (adaptState gst) o
2137 case r of
2138 Yield a o' -> do
2139 i <- inject a
2140 i `seq` return (Skip (ConcatMapUInner o' i))
2141 Skip o' -> return $ Skip (ConcatMapUOuter o')
2142 Stop -> return $ Stop
2144 step _ (ConcatMapUInner o i) = do
2145 r <- istep i
2146 return $ case r of
2147 Yield x i' -> Yield x (ConcatMapUInner o i')
2148 Skip i' -> Skip (ConcatMapUInner o i')
2149 Stop -> Skip (ConcatMapUOuter o)
2151data ConcatUnfoldInterleaveState o i =
2152 ConcatUnfoldInterleaveOuter o [i]
2153 | ConcatUnfoldInterleaveInner o [i]
2154 | ConcatUnfoldInterleaveInnerL [i] [i]
2155 | ConcatUnfoldInterleaveInnerR [i] [i]
2157-- XXX use arrays to store state instead of lists.
2158-- XXX In general we can use different scheduling strategies e.g. how to
2159-- schedule the outer vs inner loop or assigning weights to different streams
2160-- or outer and inner loops.
2162-- After a yield, switch to the next stream. Do not switch streams on Skip.
2163-- Yield from outer stream switches to the inner stream.
2165-- There are two choices here, (1) exhaust the outer stream first and then
2166-- start yielding from the inner streams, this is much simpler to implement,
2167-- (2) yield at least one element from an inner stream before going back to
2168-- outer stream and opening the next stream from it.
2170-- Ideally, we need some scheduling bias to inner streams vs outer stream.
2171-- Maybe we can configure the behavior.
2173{-# INLINE_NORMAL concatUnfoldInterleave #-}
2174concatUnfoldInterleave :: Monad m => Unfold m a b -> Stream m a -> Stream m b
2175concatUnfoldInterleave (Unfold istep inject) (Stream ostep ost) =
2176 Stream step (ConcatUnfoldInterleaveOuter ost [])
2177 where
2178 {-# INLINE_LATE step #-}
2179 step gst (ConcatUnfoldInterleaveOuter o ls) = do
2180 r <- ostep (adaptState gst) o
2181 case r of
2182 Yield a o' -> do
2183 i <- inject a
2184 i `seq` return (Skip (ConcatUnfoldInterleaveInner o' (i : ls)))
2185 Skip o' -> return $ Skip (ConcatUnfoldInterleaveOuter o' ls)
2186 Stop -> return $ Skip (ConcatUnfoldInterleaveInnerL ls [])
2188 step _ (ConcatUnfoldInterleaveInner _ []) = undefined
2189 step _ (ConcatUnfoldInterleaveInner o (st:ls)) = do
2190 r <- istep st
2191 return $ case r of
2192 Yield x s -> Yield x (ConcatUnfoldInterleaveOuter o (s:ls))
2193 Skip s -> Skip (ConcatUnfoldInterleaveInner o (s:ls))
2194 Stop -> Skip (ConcatUnfoldInterleaveOuter o ls)
2196 step _ (ConcatUnfoldInterleaveInnerL [] []) = return Stop
2197 step _ (ConcatUnfoldInterleaveInnerL [] rs) =
2198 return $ Skip (ConcatUnfoldInterleaveInnerR [] rs)
2200 step _ (ConcatUnfoldInterleaveInnerL (st:ls) rs) = do
2201 r <- istep st
2202 return $ case r of
2203 Yield x s -> Yield x (ConcatUnfoldInterleaveInnerL ls (s:rs))
2204 Skip s -> Skip (ConcatUnfoldInterleaveInnerL (s:ls) rs)
2205 Stop -> Skip (ConcatUnfoldInterleaveInnerL ls rs)
2207 step _ (ConcatUnfoldInterleaveInnerR [] []) = return Stop
2208 step _ (ConcatUnfoldInterleaveInnerR ls []) =
2209 return $ Skip (ConcatUnfoldInterleaveInnerL ls [])
2211 step _ (ConcatUnfoldInterleaveInnerR ls (st:rs)) = do
2212 r <- istep st
2213 return $ case r of
2214 Yield x s -> Yield x (ConcatUnfoldInterleaveInnerR (s:ls) rs)
2215 Skip s -> Skip (ConcatUnfoldInterleaveInnerR ls (s:rs))
2216 Stop -> Skip (ConcatUnfoldInterleaveInnerR ls rs)
2218-- XXX In general we can use different scheduling strategies e.g. how to
2219-- schedule the outer vs inner loop or assigning weights to different streams
2220-- or outer and inner loops.
2222-- This could be inefficient if the tasks are too small.
2224-- Compared to concatUnfoldInterleave this one switches streams on Skips.
2226{-# INLINE_NORMAL concatUnfoldRoundrobin #-}
2227concatUnfoldRoundrobin :: Monad m => Unfold m a b -> Stream m a -> Stream m b
2228concatUnfoldRoundrobin (Unfold istep inject) (Stream ostep ost) =
2229 Stream step (ConcatUnfoldInterleaveOuter ost [])
2230 where
2231 {-# INLINE_LATE step #-}
2232 step gst (ConcatUnfoldInterleaveOuter o ls) = do
2233 r <- ostep (adaptState gst) o
2234 case r of
2235 Yield a o' -> do
2236 i <- inject a
2237 i `seq` return (Skip (ConcatUnfoldInterleaveInner o' (i : ls)))
2238 Skip o' -> return $ Skip (ConcatUnfoldInterleaveInner o' ls)
2239 Stop -> return $ Skip (ConcatUnfoldInterleaveInnerL ls [])
2241 step _ (ConcatUnfoldInterleaveInner o []) =
2242 return $ Skip (ConcatUnfoldInterleaveOuter o [])
2244 step _ (ConcatUnfoldInterleaveInner o (st:ls)) = do
2245 r <- istep st
2246 return $ case r of
2247 Yield x s -> Yield x (ConcatUnfoldInterleaveOuter o (s:ls))
2248 Skip s -> Skip (ConcatUnfoldInterleaveOuter o (s:ls))
2249 Stop -> Skip (ConcatUnfoldInterleaveOuter o ls)
2251 step _ (ConcatUnfoldInterleaveInnerL [] []) = return Stop
2252 step _ (ConcatUnfoldInterleaveInnerL [] rs) =
2253 return $ Skip (ConcatUnfoldInterleaveInnerR [] rs)
2255 step _ (ConcatUnfoldInterleaveInnerL (st:ls) rs) = do
2256 r <- istep st
2257 return $ case r of
2258 Yield x s -> Yield x (ConcatUnfoldInterleaveInnerL ls (s:rs))
2259 Skip s -> Skip (ConcatUnfoldInterleaveInnerL ls (s:rs))
2260 Stop -> Skip (ConcatUnfoldInterleaveInnerL ls rs)
2262 step _ (ConcatUnfoldInterleaveInnerR [] []) = return Stop
2263 step _ (ConcatUnfoldInterleaveInnerR ls []) =
2264 return $ Skip (ConcatUnfoldInterleaveInnerL ls [])
2266 step _ (ConcatUnfoldInterleaveInnerR ls (st:rs)) = do
2267 r <- istep st
2268 return $ case r of
2269 Yield x s -> Yield x (ConcatUnfoldInterleaveInnerR (s:ls) rs)
2270 Skip s -> Skip (ConcatUnfoldInterleaveInnerR (s:ls) rs)
2271 Stop -> Skip (ConcatUnfoldInterleaveInnerR ls rs)
2273data AppendState s1 s2 = AppendFirst s1 | AppendSecond s2
2275-- Note that this could be much faster compared to the CPS stream. However, as
2276-- the number of streams being composed increases this may become expensive.
2277-- Need to see where the breaking point is between the two.
2279{-# INLINE_NORMAL append #-}
2280append :: Monad m => Stream m a -> Stream m a -> Stream m a
2281append (Stream step1 state1) (Stream step2 state2) =
2282 Stream step (AppendFirst state1)
2284 where
2286 {-# INLINE_LATE step #-}
2287 step gst (AppendFirst st) = do
2288 r <- step1 gst st
2289 return $ case r of
2290 Yield a s -> Yield a (AppendFirst s)
2291 Skip s -> Skip (AppendFirst s)
2292 Stop -> Skip (AppendSecond state2)
2294 step gst (AppendSecond st) = do
2295 r <- step2 gst st
2296 return $ case r of
2297 Yield a s -> Yield a (AppendSecond s)
2298 Skip s -> Skip (AppendSecond s)
2299 Stop -> Stop
2301data InterleaveState s1 s2 = InterleaveFirst s1 s2 | InterleaveSecond s1 s2
2302 | InterleaveSecondOnly s2 | InterleaveFirstOnly s1
2304{-# INLINE_NORMAL interleave #-}
2305interleave :: Monad m => Stream m a -> Stream m a -> Stream m a
2306interleave (Stream step1 state1) (Stream step2 state2) =
2307 Stream step (InterleaveFirst state1 state2)
2309 where
2311 {-# INLINE_LATE step #-}
2312 step gst (InterleaveFirst st1 st2) = do
2313 r <- step1 gst st1
2314 return $ case r of
2315 Yield a s -> Yield a (InterleaveSecond s st2)
2316 Skip s -> Skip (InterleaveFirst s st2)
2317 Stop -> Skip (InterleaveSecondOnly st2)
2319 step gst (InterleaveSecond st1 st2) = do
2320 r <- step2 gst st2
2321 return $ case r of
2322 Yield a s -> Yield a (InterleaveFirst st1 s)
2323 Skip s -> Skip (InterleaveSecond st1 s)
2324 Stop -> Skip (InterleaveFirstOnly st1)
2326 step gst (InterleaveFirstOnly st1) = do
2327 r <- step1 gst st1
2328 return $ case r of
2329 Yield a s -> Yield a (InterleaveFirstOnly s)
2330 Skip s -> Skip (InterleaveFirstOnly s)
2331 Stop -> Stop
2333 step gst (InterleaveSecondOnly st2) = do
2334 r <- step2 gst st2
2335 return $ case r of
2336 Yield a s -> Yield a (InterleaveSecondOnly s)
2337 Skip s -> Skip (InterleaveSecondOnly s)
2338 Stop -> Stop
2340{-# INLINE_NORMAL interleaveMin #-}
2341interleaveMin :: Monad m => Stream m a -> Stream m a -> Stream m a
2342interleaveMin (Stream step1 state1) (Stream step2 state2) =
2343 Stream step (InterleaveFirst state1 state2)
2345 where
2347 {-# INLINE_LATE step #-}
2348 step gst (InterleaveFirst st1 st2) = do
2349 r <- step1 gst st1
2350 return $ case r of
2351 Yield a s -> Yield a (InterleaveSecond s st2)
2352 Skip s -> Skip (InterleaveFirst s st2)
2353 Stop -> Stop
2355 step gst (InterleaveSecond st1 st2) = do
2356 r <- step2 gst st2
2357 return $ case r of
2358 Yield a s -> Yield a (InterleaveFirst st1 s)
2359 Skip s -> Skip (InterleaveSecond st1 s)
2360 Stop -> Stop
2362 step _ (InterleaveFirstOnly _) = undefined
2363 step _ (InterleaveSecondOnly _) = undefined
2365{-# INLINE_NORMAL interleaveSuffix #-}
2366interleaveSuffix :: Monad m => Stream m a -> Stream m a -> Stream m a
2367interleaveSuffix (Stream step1 state1) (Stream step2 state2) =
2368 Stream step (InterleaveFirst state1 state2)
2370 where
2372 {-# INLINE_LATE step #-}
2373 step gst (InterleaveFirst st1 st2) = do
2374 r <- step1 gst st1
2375 return $ case r of
2376 Yield a s -> Yield a (InterleaveSecond s st2)
2377 Skip s -> Skip (InterleaveFirst s st2)
2378 Stop -> Stop
2380 step gst (InterleaveSecond st1 st2) = do
2381 r <- step2 gst st2
2382 return $ case r of
2383 Yield a s -> Yield a (InterleaveFirst st1 s)
2384 Skip s -> Skip (InterleaveSecond st1 s)
2385 Stop -> Skip (InterleaveFirstOnly st1)
2387 step gst (InterleaveFirstOnly st1) = do
2388 r <- step1 gst st1
2389 return $ case r of
2390 Yield a s -> Yield a (InterleaveFirstOnly s)
2391 Skip s -> Skip (InterleaveFirstOnly s)
2392 Stop -> Stop
2394 step _ (InterleaveSecondOnly _) = undefined
2396data InterleaveInfixState s1 s2 a
2397 = InterleaveInfixFirst s1 s2
2398 | InterleaveInfixSecondBuf s1 s2
2399 | InterleaveInfixSecondYield s1 s2 a
2400 | InterleaveInfixFirstYield s1 s2 a
2401 | InterleaveInfixFirstOnly s1
2403{-# INLINE_NORMAL interleaveInfix #-}
2404interleaveInfix :: Monad m => Stream m a -> Stream m a -> Stream m a
2405interleaveInfix (Stream step1 state1) (Stream step2 state2) =
2406 Stream step (InterleaveInfixFirst state1 state2)
2408 where
2410 {-# INLINE_LATE step #-}
2411 step gst (InterleaveInfixFirst st1 st2) = do
2412 r <- step1 gst st1
2413 return $ case r of
2414 Yield a s -> Yield a (InterleaveInfixSecondBuf s st2)
2415 Skip s -> Skip (InterleaveInfixFirst s st2)
2416 Stop -> Stop
2418 step gst (InterleaveInfixSecondBuf st1 st2) = do
2419 r <- step2 gst st2
2420 return $ case r of
2421 Yield a s -> Skip (InterleaveInfixSecondYield st1 s a)
2422 Skip s -> Skip (InterleaveInfixSecondBuf st1 s)
2423 Stop -> Skip (InterleaveInfixFirstOnly st1)
2425 step gst (InterleaveInfixSecondYield st1 st2 x) = do
2426 r <- step1 gst st1
2427 return $ case r of
2428 Yield a s -> Yield x (InterleaveInfixFirstYield s st2 a)
2429 Skip s -> Skip (InterleaveInfixSecondYield s st2 x)
2430 Stop -> Stop
2432 step _ (InterleaveInfixFirstYield st1 st2 x) = do
2433 return $ Yield x (InterleaveInfixSecondBuf st1 st2)
2435 step gst (InterleaveInfixFirstOnly st1) = do
2436 r <- step1 gst st1
2437 return $ case r of
2438 Yield a s -> Yield a (InterleaveInfixFirstOnly s)
2439 Skip s -> Skip (InterleaveInfixFirstOnly s)
2440 Stop -> Stop
2442{-# INLINE_NORMAL roundRobin #-}
2443roundRobin :: Monad m => Stream m a -> Stream m a -> Stream m a
2444roundRobin (Stream step1 state1) (Stream step2 state2) =
2445 Stream step (InterleaveFirst state1 state2)
2447 where
2449 {-# INLINE_LATE step #-}
2450 step gst (InterleaveFirst st1 st2) = do
2451 r <- step1 gst st1
2452 return $ case r of
2453 Yield a s -> Yield a (InterleaveSecond s st2)
2454 Skip s -> Skip (InterleaveSecond s st2)
2455 Stop -> Skip (InterleaveSecondOnly st2)
2457 step gst (InterleaveSecond st1 st2) = do
2458 r <- step2 gst st2
2459 return $ case r of
2460 Yield a s -> Yield a (InterleaveFirst st1 s)
2461 Skip s -> Skip (InterleaveFirst st1 s)
2462 Stop -> Skip (InterleaveFirstOnly st1)
2464 step gst (InterleaveSecondOnly st2) = do
2465 r <- step2 gst st2
2466 return $ case r of
2467 Yield a s -> Yield a (InterleaveSecondOnly s)
2468 Skip s -> Skip (InterleaveSecondOnly s)
2469 Stop -> Stop
2471 step gst (InterleaveFirstOnly st1) = do
2472 r <- step1 gst st1
2473 return $ case r of
2474 Yield a s -> Yield a (InterleaveFirstOnly s)
2475 Skip s -> Skip (InterleaveFirstOnly s)
2476 Stop -> Stop
2478data ICUState s1 s2 i1 i2 =
2479 ICUFirst s1 s2
2480 | ICUSecond s1 s2
2481 | ICUSecondOnly s2
2482 | ICUFirstOnly s1
2483 | ICUFirstInner s1 s2 i1
2484 | ICUSecondInner s1 s2 i2
2485 | ICUFirstOnlyInner s1 i1
2486 | ICUSecondOnlyInner s2 i2
2488-- | Interleave streams (full streams, not the elements) unfolded from two
2489-- input streams and concat. Stop when the first stream stops. If the second
2490-- stream ends before the first one then first stream still keeps running alone
2491-- without any interleaving with the second stream.
2493-- [a1, a2, ... an] [b1, b2 ...]
2494-- => [streamA1, streamA2, ... streamAn] [streamB1, streamB2, ...]
2495-- => [streamA1, streamB1, streamA2...StreamAn, streamBn]
2496-- => [a11, a12, ...a1j, b11, b12, ...b1k, a21, a22, ...]
2498{-# INLINE_NORMAL gintercalateSuffix #-}
2499gintercalateSuffix
2500 :: Monad m
2501 => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c
2502gintercalateSuffix
2503 (Unfold istep1 inject1) (Stream step1 state1)
2504 (Unfold istep2 inject2) (Stream step2 state2) =
2505 Stream step (ICUFirst state1 state2)
2507 where
2509 {-# INLINE_LATE step #-}
2510 step gst (ICUFirst s1 s2) = do
2511 r <- step1 (adaptState gst) s1
2512 case r of
2513 Yield a s -> do
2514 i <- inject1 a
2515 i `seq` return (Skip (ICUFirstInner s s2 i))
2516 Skip s -> return $ Skip (ICUFirst s s2)
2517 Stop -> return Stop
2519 step gst (ICUFirstOnly s1) = do
2520 r <- step1 (adaptState gst) s1
2521 case r of
2522 Yield a s -> do
2523 i <- inject1 a
2524 i `seq` return (Skip (ICUFirstOnlyInner s i))
2525 Skip s -> return $ Skip (ICUFirstOnly s)
2526 Stop -> return Stop
2528 step _ (ICUFirstInner s1 s2 i1) = do
2529 r <- istep1 i1
2530 return $ case r of
2531 Yield x i' -> Yield x (ICUFirstInner s1 s2 i')
2532 Skip i' -> Skip (ICUFirstInner s1 s2 i')
2533 Stop -> Skip (ICUSecond s1 s2)
2535 step _ (ICUFirstOnlyInner s1 i1) = do
2536 r <- istep1 i1
2537 return $ case r of
2538 Yield x i' -> Yield x (ICUFirstOnlyInner s1 i')
2539 Skip i' -> Skip (ICUFirstOnlyInner s1 i')
2540 Stop -> Skip (ICUFirstOnly s1)
2542 step gst (ICUSecond s1 s2) = do
2543 r <- step2 (adaptState gst) s2
2544 case r of
2545 Yield a s -> do
2546 i <- inject2 a
2547 i `seq` return (Skip (ICUSecondInner s1 s i))
2548 Skip s -> return $ Skip (ICUSecond s1 s)
2549 Stop -> return $ Skip (ICUFirstOnly s1)
2551 step _ (ICUSecondInner s1 s2 i2) = do
2552 r <- istep2 i2
2553 return $ case r of
2554 Yield x i' -> Yield x (ICUSecondInner s1 s2 i')
2555 Skip i' -> Skip (ICUSecondInner s1 s2 i')
2556 Stop -> Skip (ICUFirst s1 s2)
2558 step _ (ICUSecondOnly _s2) = undefined
2559 step _ (ICUSecondOnlyInner _s2 _i2) = undefined
2561data InterposeSuffixState s1 i1 =
2562 InterposeSuffixFirst s1
2563 -- | InterposeSuffixFirstYield s1 i1
2564 | InterposeSuffixFirstInner s1 i1
2565 | InterposeSuffixSecond s1
2567-- Note that if an unfolded layer turns out to be nil we still emit the
2568-- separator effect. An alternate behavior could be to emit the separator
2569-- effect only if at least one element has been yielded by the unfolding.
2570-- However, that becomes a bit complicated, so we have chosen the former
2571-- behvaior for now.
2572{-# INLINE_NORMAL interposeSuffix #-}
2573interposeSuffix
2574 :: Monad m
2575 => m c -> Unfold m b c -> Stream m b -> Stream m c
2576interposeSuffix
2577 action
2578 (Unfold istep1 inject1) (Stream step1 state1) =
2579 Stream step (InterposeSuffixFirst state1)
2581 where
2583 {-# INLINE_LATE step #-}
2584 step gst (InterposeSuffixFirst s1) = do
2585 r <- step1 (adaptState gst) s1
2586 case r of
2587 Yield a s -> do
2588 i <- inject1 a
2589 i `seq` return (Skip (InterposeSuffixFirstInner s i))
2590 -- i `seq` return (Skip (InterposeSuffixFirstYield s i))
2591 Skip s -> return $ Skip (InterposeSuffixFirst s)
2592 Stop -> return Stop
2594 {-
2595 step _ (InterposeSuffixFirstYield s1 i1) = do
2596 r <- istep1 i1
2597 return $ case r of
2598 Yield x i' -> Yield x (InterposeSuffixFirstInner s1 i')
2599 Skip i' -> Skip (InterposeSuffixFirstYield s1 i')
2600 Stop -> Skip (InterposeSuffixFirst s1)
2601 -}
2603 step _ (InterposeSuffixFirstInner s1 i1) = do
2604 r <- istep1 i1
2605 return $ case r of
2606 Yield x i' -> Yield x (InterposeSuffixFirstInner s1 i')
2607 Skip i' -> Skip (InterposeSuffixFirstInner s1 i')
2608 Stop -> Skip (InterposeSuffixSecond s1)
2610 step _ (InterposeSuffixSecond s1) = do
2611 r <- action
2612 return $ Yield r (InterposeSuffixFirst s1)
2614data ICALState s1 s2 i1 i2 a =
2615 ICALFirst s1 s2
2616 -- | ICALFirstYield s1 s2 i1
2617 | ICALFirstInner s1 s2 i1
2618 | ICALFirstOnly s1
2619 | ICALFirstOnlyInner s1 i1
2620 | ICALSecondInject s1 s2
2621 | ICALFirstInject s1 s2 i2
2622 -- | ICALFirstBuf s1 s2 i1 i2
2623 | ICALSecondInner s1 s2 i1 i2
2624 -- -- | ICALSecondInner s1 s2 i1 i2 a
2625 -- -- | ICALFirstResume s1 s2 i1 i2 a
2627-- | Interleave streams (full streams, not the elements) unfolded from two
2628-- input streams and concat. Stop when the first stream stops. If the second
2629-- stream ends before the first one then first stream still keeps running alone
2630-- without any interleaving with the second stream.
2632-- [a1, a2, ... an] [b1, b2 ...]
2633-- => [streamA1, streamA2, ... streamAn] [streamB1, streamB2, ...]
2634-- => [streamA1, streamB1, streamA2...StreamAn, streamBn]
2635-- => [a11, a12, ...a1j, b11, b12, ...b1k, a21, a22, ...]
2637{-# INLINE_NORMAL gintercalate #-}
2638gintercalate
2639 :: Monad m
2640 => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c
2641gintercalate
2642 (Unfold istep1 inject1) (Stream step1 state1)
2643 (Unfold istep2 inject2) (Stream step2 state2) =
2644 Stream step (ICALFirst state1 state2)
2646 where
2648 {-# INLINE_LATE step #-}
2649 step gst (ICALFirst s1 s2) = do
2650 r <- step1 (adaptState gst) s1
2651 case r of
2652 Yield a s -> do
2653 i <- inject1 a
2654 i `seq` return (Skip (ICALFirstInner s s2 i))
2655 -- i `seq` return (Skip (ICALFirstYield s s2 i))
2656 Skip s -> return $ Skip (ICALFirst s s2)
2657 Stop -> return Stop
2659 {-
2660 step _ (ICALFirstYield s1 s2 i1) = do
2661 r <- istep1 i1
2662 return $ case r of
2663 Yield x i' -> Yield x (ICALFirstInner s1 s2 i')
2664 Skip i' -> Skip (ICALFirstYield s1 s2 i')
2665 Stop -> Skip (ICALFirst s1 s2)
2666 -}
2668 step _ (ICALFirstInner s1 s2 i1) = do
2669 r <- istep1 i1
2670 return $ case r of
2671 Yield x i' -> Yield x (ICALFirstInner s1 s2 i')
2672 Skip i' -> Skip (ICALFirstInner s1 s2 i')
2673 Stop -> Skip (ICALSecondInject s1 s2)
2675 step gst (ICALFirstOnly s1) = do
2676 r <- step1 (adaptState gst) s1
2677 case r of
2678 Yield a s -> do
2679 i <- inject1 a
2680 i `seq` return (Skip (ICALFirstOnlyInner s i))
2681 Skip s -> return $ Skip (ICALFirstOnly s)
2682 Stop -> return Stop
2684 step _ (ICALFirstOnlyInner s1 i1) = do
2685 r <- istep1 i1
2686 return $ case r of
2687 Yield x i' -> Yield x (ICALFirstOnlyInner s1 i')
2688 Skip i' -> Skip (ICALFirstOnlyInner s1 i')
2689 Stop -> Skip (ICALFirstOnly s1)
2691 -- We inject the second stream even before checking if the first stream
2692 -- would yield any more elements. There is no clear choice whether we
2693 -- should do this before or after that. Doing it after may make the state
2694 -- machine a bit simpler though.
2695 step gst (ICALSecondInject s1 s2) = do
2696 r <- step2 (adaptState gst) s2
2697 case r of
2698 Yield a s -> do
2699 i <- inject2 a
2700 i `seq` return (Skip (ICALFirstInject s1 s i))
2701 Skip s -> return $ Skip (ICALSecondInject s1 s)
2702 Stop -> return $ Skip (ICALFirstOnly s1)
2704 step gst (ICALFirstInject s1 s2 i2) = do
2705 r <- step1 (adaptState gst) s1
2706 case r of
2707 Yield a s -> do
2708 i <- inject1 a
2709 i `seq` return (Skip (ICALSecondInner s s2 i i2))
2710 -- i `seq` return (Skip (ICALFirstBuf s s2 i i2))
2711 Skip s -> return $ Skip (ICALFirstInject s s2 i2)
2712 Stop -> return Stop
2714 {-
2715 step _ (ICALFirstBuf s1 s2 i1 i2) = do
2716 r <- istep1 i1
2717 return $ case r of
2718 Yield x i' -> Skip (ICALSecondInner s1 s2 i' i2 x)
2719 Skip i' -> Skip (ICALFirstBuf s1 s2 i' i2)
2720 Stop -> Stop
2722 step _ (ICALSecondInner s1 s2 i1 i2 v) = do
2723 r <- istep2 i2
2724 return $ case r of
2725 Yield x i' -> Yield x (ICALSecondInner s1 s2 i1 i' v)
2726 Skip i' -> Skip (ICALSecondInner s1 s2 i1 i' v)
2727 Stop -> Skip (ICALFirstResume s1 s2 i1 i2 v)
2728 -}
2730 step _ (ICALSecondInner s1 s2 i1 i2) = do
2731 r <- istep2 i2
2732 return $ case r of
2733 Yield x i' -> Yield x (ICALSecondInner s1 s2 i1 i')
2734 Skip i' -> Skip (ICALSecondInner s1 s2 i1 i')
2735 Stop -> Skip (ICALFirstInner s1 s2 i1)
2736 -- Stop -> Skip (ICALFirstResume s1 s2 i1 i2)
2738 {-
2739 step _ (ICALFirstResume s1 s2 i1 i2 x) = do
2740 return $ Yield x (ICALFirstInner s1 s2 i1 i2)
2741 -}
2743data InterposeState s1 i1 a =
2744 InterposeFirst s1
2745 -- | InterposeFirstYield s1 i1
2746 | InterposeFirstInner s1 i1
2747 | InterposeFirstInject s1
2748 -- | InterposeFirstBuf s1 i1
2749 | InterposeSecondYield s1 i1
2750 -- -- | InterposeSecondYield s1 i1 a
2751 -- -- | InterposeFirstResume s1 i1 a
2753-- Note that this only interposes the pure values, we may run many effects to
2754-- generate those values as some effects may not generate anything (Skip).
2755{-# INLINE_NORMAL interpose #-}
2756interpose :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c
2757interpose
2758 action
2759 (Unfold istep1 inject1) (Stream step1 state1) =
2760 Stream step (InterposeFirst state1)
2762 where
2764 {-# INLINE_LATE step #-}
2765 step gst (InterposeFirst s1) = do
2766 r <- step1 (adaptState gst) s1
2767 case r of
2768 Yield a s -> do
2769 i <- inject1 a
2770 i `seq` return (Skip (InterposeFirstInner s i))
2771 -- i `seq` return (Skip (InterposeFirstYield s i))
2772 Skip s -> return $ Skip (InterposeFirst s)
2773 Stop -> return Stop
2775 {-
2776 step _ (InterposeFirstYield s1 i1) = do
2777 r <- istep1 i1
2778 return $ case r of
2779 Yield x i' -> Yield x (InterposeFirstInner s1 i')
2780 Skip i' -> Skip (InterposeFirstYield s1 i')
2781 Stop -> Skip (InterposeFirst s1)
2782 -}
2784 step _ (InterposeFirstInner s1 i1) = do
2785 r <- istep1 i1
2786 return $ case r of
2787 Yield x i' -> Yield x (InterposeFirstInner s1 i')
2788 Skip i' -> Skip (InterposeFirstInner s1 i')
2789 Stop -> Skip (InterposeFirstInject s1)
2791 step gst (InterposeFirstInject s1) = do
2792 r <- step1 (adaptState gst) s1
2793 case r of
2794 Yield a s -> do
2795 i <- inject1 a
2796 -- i `seq` return (Skip (InterposeFirstBuf s i))
2797 i `seq` return (Skip (InterposeSecondYield s i))
2798 Skip s -> return $ Skip (InterposeFirstInject s)
2799 Stop -> return Stop
2801 {-
2802 step _ (InterposeFirstBuf s1 i1) = do
2803 r <- istep1 i1
2804 return $ case r of
2805 Yield x i' -> Skip (InterposeSecondYield s1 i' x)
2806 Skip i' -> Skip (InterposeFirstBuf s1 i')
2807 Stop -> Stop
2808 -}
2810 {-
2811 step _ (InterposeSecondYield s1 i1 v) = do
2812 r <- action
2813 return $ Yield r (InterposeFirstResume s1 i1 v)
2814 -}
2815 step _ (InterposeSecondYield s1 i1) = do
2816 r <- action
2817 return $ Yield r (InterposeFirstInner s1 i1)
2819 {-
2820 step _ (InterposeFirstResume s1 i1 v) = do
2821 return $ Yield v (InterposeFirstInner s1 i1)
2822 -}
2824------------------------------------------------------------------------------
2825-- Exceptions
2826------------------------------------------------------------------------------
2828data GbracketState s1 s2 v
2829 = GBracketInit
2830 | GBracketNormal s1 v
2831 | GBracketException s2
2833-- | The most general bracketing and exception combinator. All other
2834-- combinators can be expressed in terms of this combinator. This can also be
2835-- used for cases which are not covered by the standard combinators.
2837-- /Internal/
2839{-# INLINE_NORMAL gbracket #-}
2840gbracket
2841 :: Monad m
2842 => m c -- ^ before
2843 -> (forall s. m s -> m (Either e s)) -- ^ try (exception handling)
2844 -> (c -> m d) -- ^ after, on normal stop
2845 -> (c -> e -> Stream m b) -- ^ on exception
2846 -> (c -> Stream m b) -- ^ stream generator
2847 -> Stream m b
2848gbracket bef exc aft fexc fnormal =
2849 Stream step GBracketInit
2851 where
2853 {-# INLINE_LATE step #-}
2854 step _ GBracketInit = do
2855 r <- bef
2856 return $ Skip $ GBracketNormal (fnormal r) r
2858 step gst (GBracketNormal (UnStream step1 st) v) = do
2859 res <- exc $ step1 gst st
2860 case res of
2861 Right r -> case r of
2862 Yield x s ->
2863 return $ Yield x (GBracketNormal (Stream step1 s) v)
2864 Skip s -> return $ Skip (GBracketNormal (Stream step1 s) v)
2865 Stop -> aft v >> return Stop
2866 Left e -> return $ Skip (GBracketException (fexc v e))
2867 step gst (GBracketException (UnStream step1 st)) = do
2868 res <- step1 gst st
2869 case res of
2870 Yield x s -> return $ Yield x (GBracketException (Stream step1 s))
2871 Skip s -> return $ Skip (GBracketException (Stream step1 s))
2872 Stop -> return Stop
2874-- | Run a side effect before the stream yields its first element.
2875{-# INLINE_NORMAL before #-}
2876before :: Monad m => m b -> Stream m a -> Stream m a
2877before action (Stream step state) = Stream step' Nothing
2879 where
2881 {-# INLINE_LATE step' #-}
2882 step' _ Nothing = action >> return (Skip (Just state))
2884 step' gst (Just st) = do
2885 res <- step gst st
2886 case res of
2887 Yield x s -> return $ Yield x (Just s)
2888 Skip s -> return $ Skip (Just s)
2889 Stop -> return Stop
2891-- | Run a side effect whenever the stream stops normally.
2892{-# INLINE_NORMAL after #-}
2893after :: Monad m => m b -> Stream m a -> Stream m a
2894after action (Stream step state) = Stream step' state
2896 where
2898 {-# INLINE_LATE step' #-}
2899 step' gst st = do
2900 res <- step gst st
2901 case res of
2902 Yield x s -> return $ Yield x s
2903 Skip s -> return $ Skip s
2904 Stop -> action >> return Stop
2906-- XXX These combinators are expensive due to the call to
2907-- onException/handle/try on each step. Therefore, when possible, they should
2908-- be called in an outer loop where we perform less iterations. For example, we
2909-- cannot call them on each iteration in a char stream, instead we can call
2910-- them when doing an IO on an array.
2912-- XXX For high performance error checks in busy streams we may need another
2913-- Error constructor in step.
2915-- | Run a side effect whenever the stream aborts due to an exception. The
2916-- exception is not caught, simply rethrown.
2917{-# INLINE_NORMAL onException #-}
2918onException :: MonadCatch m => m b -> Stream m a -> Stream m a
2919onException action str =
2920 gbracket (return ()) MC.try return
2921 (\_ (e :: MC.SomeException) -> nilM (action >> MC.throwM e))
2922 (\_ -> str)
2924{-# INLINE_NORMAL _onException #-}
2925_onException :: MonadCatch m => m b -> Stream m a -> Stream m a
2926_onException action (Stream step state) = Stream step' state
2928 where
2930 {-# INLINE_LATE step' #-}
2931 step' gst st = do
2932 res <- step gst st `MC.onException` action
2933 case res of
2934 Yield x s -> return $ Yield x s
2935 Skip s -> return $ Skip s
2936 Stop -> return Stop
2938-- XXX bracket is like concatMap, it generates a stream and then flattens it.
2939-- Like concatMap it has 10x worse performance compared to linear fused
2940-- compositions.
2942-- | Run the first action before the stream starts and remember its output,
2943-- generate a stream using the output, run the second action providing the
2944-- remembered value as an argument whenever the stream ends normally or due to
2945-- an exception.
2946{-# INLINE_NORMAL bracket #-}
2947bracket :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
2948bracket bef aft bet =
2949 gbracket bef MC.try aft
2950 (\a (e :: SomeException) -> nilM (aft a >> MC.throwM e)) bet
2952data BracketState s v = BracketInit | BracketRun s v
2954{-# INLINE_NORMAL _bracket #-}
2955_bracket :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
2956_bracket bef aft bet = Stream step' BracketInit
2958 where
2960 {-# INLINE_LATE step' #-}
2961 step' _ BracketInit = bef >>= \x -> return (Skip (BracketRun (bet x) x))
2963 -- NOTE: It is important to use UnStream instead of the Stream pattern
2964 -- here, otherwise we get huge perf degradation, see note in concatMap.
2965 step' gst (BracketRun (UnStream step state) v) = do
2966 -- res <- step gst state `MC.onException` aft v
2967 res <- MC.try $ step gst state
2968 case res of
2969 Left (e :: SomeException) -> aft v >> MC.throwM e >> return Stop
2970 Right r -> case r of
2971 Yield x s -> return $ Yield x (BracketRun (Stream step s) v)
2972 Skip s -> return $ Skip (BracketRun (Stream step s) v)
2973 Stop -> aft v >> return Stop
2975-- | Run a side effect whenever the stream stops normally or aborts due to an
2976-- exception.
2977{-# INLINE finally #-}
2978finally :: MonadCatch m => m b -> Stream m a -> Stream m a
2979-- finally action xs = after action $ onException action xs
2980finally action xs = bracket (return ()) (\_ -> action) (const xs)
2982-- | When evaluating a stream if an exception occurs, stream evaluation aborts
2983-- and the specified exception handler is run with the exception as argument.
2984{-# INLINE_NORMAL handle #-}
2985handle :: (MonadCatch m, Exception e)
2986 => (e -> Stream m a) -> Stream m a -> Stream m a
2987handle f str =
2988 gbracket (return ()) MC.try return (\_ e -> f e) (\_ -> str)
2990{-# INLINE_NORMAL _handle #-}
2991_handle :: (MonadCatch m, Exception e)
2992 => (e -> Stream m a) -> Stream m a -> Stream m a
2993_handle f (Stream step state) = Stream step' (Left state)
2995 where
2997 {-# INLINE_LATE step' #-}
2998 step' gst (Left st) = do
2999 res <- MC.try $ step gst st
3000 case res of
3001 Left e -> return $ Skip $ Right (f e)
3002 Right r -> case r of
3003 Yield x s -> return $ Yield x (Left s)
3004 Skip s -> return $ Skip (Left s)
3005 Stop -> return Stop
3007 step' gst (Right (UnStream step1 st)) = do
3008 res <- step1 gst st
3009 case res of
3010 Yield x s -> return $ Yield x (Right (Stream step1 s))
3011 Skip s -> return $ Skip (Right (Stream step1 s))
3012 Stop -> return Stop
3014-------------------------------------------------------------------------------
3015-- General transformation
3016-------------------------------------------------------------------------------
3018{-# INLINE_NORMAL transform #-}
3019transform :: Monad m => Pipe m a b -> Stream m a -> Stream m b
3020transform (Pipe pstep1 pstep2 pstate) (Stream step state) =
3021 Stream step' (Consume pstate, state)
3023 where
3025 {-# INLINE_LATE step' #-}
3027 step' gst (Consume pst, st) = pst `seq` do
3028 r <- step (adaptState gst) st
3029 case r of
3030 Yield x s -> do
3031 res <- pstep1 pst x
3032 case res of
3033 Pipe.Yield b pst' -> return $ Yield b (pst', s)
3034 Pipe.Continue pst' -> return $ Skip (pst', s)
3035 Skip s -> return $ Skip (Consume pst, s)
3036 Stop -> return Stop
3038 step' _ (Produce pst, st) = pst `seq` do
3039 res <- pstep2 pst
3040 case res of
3041 Pipe.Yield b pst' -> return $ Yield b (pst', st)
3042 Pipe.Continue pst' -> return $ Skip (pst', st)
3044------------------------------------------------------------------------------
3045-- Transformation by Folding (Scans)
3046------------------------------------------------------------------------------
3048------------------------------------------------------------------------------
3049-- Prescans
3050------------------------------------------------------------------------------
3052-- XXX Is a prescan useful, discarding the last step does not sound useful? I
3053-- am not sure about the utility of this function, so this is implemented but
3054-- not exposed. We can expose it if someone provides good reasons why this is
3055-- useful.
3057-- XXX We have to execute the stream one step ahead to know that we are at the
3058-- last step. The vector implementation of prescan executes the last fold step
3059-- but does not yield the result. This means we have executed the effect but
3060-- discarded value. This does not sound right. In this implementation we are
3061-- not executing the last fold step.
3062{-# INLINE_NORMAL prescanlM' #-}
3063prescanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
3064prescanlM' f mz (Stream step state) = Stream step' (state, mz)
3065 where
3066 {-# INLINE_LATE step' #-}
3067 step' gst (st, prev) = do
3068 r <- step (adaptState gst) st
3069 case r of
3070 Yield x s -> do
3071 acc <- prev
3072 return $ Yield acc (s, f acc x)
3073 Skip s -> return $ Skip (s, prev)
3074 Stop -> return Stop
3076{-# INLINE prescanl' #-}
3077prescanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
3078prescanl' f z = prescanlM' (\a b -> return (f a b)) (return z)
3080------------------------------------------------------------------------------
3081-- Monolithic postscans (postscan followed by a map)
3082------------------------------------------------------------------------------
3084-- The performance of a modular postscan followed by a map seems to be
3085-- equivalent to this monolithic scan followed by map therefore we may not need
3086-- this implementation. We just have it for performance comparison and in case
3087-- modular version does not perform well in some situation.
3089{-# INLINE_NORMAL postscanlMx' #-}
3090postscanlMx' :: Monad m
3091 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
3092postscanlMx' fstep begin done (Stream step state) = do
3093 Stream step' (state, begin)
3094 where
3095 {-# INLINE_LATE step' #-}
3096 step' gst (st, acc) = do
3097 r <- step (adaptState gst) st
3098 case r of
3099 Yield x s -> do
3100 old <- acc
3101 y <- fstep old x
3102 v <- done y
3103 v `seq` y `seq` return (Yield v (s, return y))
3104 Skip s -> return $ Skip (s, acc)
3105 Stop -> return Stop
3107{-# INLINE_NORMAL postscanlx' #-}
3108postscanlx' :: Monad m
3109 => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
3110postscanlx' fstep begin done s =
3111 postscanlMx' (\b a -> return (fstep b a)) (return begin) (return . done) s
3113-- XXX do we need consM strict to evaluate the begin value?
3114{-# INLINE scanlMx' #-}
3115scanlMx' :: Monad m
3116 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
3117scanlMx' fstep begin done s =
3118 (begin >>= \x -> x `seq` done x) `consM` postscanlMx' fstep begin done s
3120{-# INLINE scanlx' #-}
3121scanlx' :: Monad m
3122 => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
3123scanlx' fstep begin done s =
3124 scanlMx' (\b a -> return (fstep b a)) (return begin) (return . done) s
3126------------------------------------------------------------------------------
3127-- postscans
3128------------------------------------------------------------------------------
3130{-# INLINE_NORMAL postscanlM' #-}
3131postscanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
3132postscanlM' fstep begin (Stream step state) =
3133 begin `seq` Stream step' (state, begin)
3134 where
3135 {-# INLINE_LATE step' #-}
3136 step' gst (st, acc) = acc `seq` do
3137 r <- step (adaptState gst) st
3138 case r of
3139 Yield x s -> do
3140 y <- fstep acc x
3141 y `seq` return (Yield y (s, y))
3142 Skip s -> return $ Skip (s, acc)
3143 Stop -> return Stop
3145{-# INLINE_NORMAL postscanl' #-}
3146postscanl' :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
3147postscanl' f = postscanlM' (\a b -> return (f a b))
3149{-# INLINE_NORMAL postscanlM #-}
3150postscanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
3151postscanlM fstep begin (Stream step state) = Stream step' (state, begin)
3152 where
3153 {-# INLINE_LATE step' #-}
3154 step' gst (st, acc) = do
3155 r <- step (adaptState gst) st
3156 case r of
3157 Yield x s -> do
3158 y <- fstep acc x
3159 return (Yield y (s, y))
3160 Skip s -> return $ Skip (s, acc)
3161 Stop -> return Stop
3163{-# INLINE_NORMAL postscanl #-}
3164postscanl :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
3165postscanl f = postscanlM (\a b -> return (f a b))
3167{-# INLINE_NORMAL scanlM' #-}
3168scanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
3169scanlM' fstep begin s = begin `seq` (begin `cons` postscanlM' fstep begin s)
3171{-# INLINE scanl' #-}
3172scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
3173scanl' f = scanlM' (\a b -> return (f a b))
3175{-# INLINE_NORMAL scanlM #-}
3176scanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
3177scanlM fstep begin s = begin `cons` postscanlM fstep begin s
3179{-# INLINE scanl #-}
3180scanl :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
3181scanl f = scanlM (\a b -> return (f a b))
3183{-# INLINE_NORMAL scanl1M #-}
3184scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
3185scanl1M fstep (Stream step state) = Stream step' (state, Nothing)
3186 where
3187 {-# INLINE_LATE step' #-}
3188 step' gst (st, Nothing) = do
3189 r <- step gst st
3190 case r of
3191 Yield x s -> return $ Yield x (s, Just x)
3192 Skip s -> return $ Skip (s, Nothing)
3193 Stop -> return Stop
3195 step' gst (st, Just acc) = do
3196 r <- step gst st
3197 case r of
3198 Yield y s -> do
3199 z <- fstep acc y
3200 return $ Yield z (s, Just z)
3201 Skip s -> return $ Skip (s, Just acc)
3202 Stop -> return Stop
3204{-# INLINE scanl1 #-}
3205scanl1 :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
3206scanl1 f = scanl1M (\x y -> return (f x y))
3208{-# INLINE_NORMAL scanl1M' #-}
3209scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
3210scanl1M' fstep (Stream step state) = Stream step' (state, Nothing)
3211 where
3212 {-# INLINE_LATE step' #-}
3213 step' gst (st, Nothing) = do
3214 r <- step gst st
3215 case r of
3216 Yield x s -> x `seq` return $ Yield x (s, Just x)
3217 Skip s -> return $ Skip (s, Nothing)
3218 Stop -> return Stop
3220 step' gst (st, Just acc) = acc `seq` do
3221 r <- step gst st
3222 case r of
3223 Yield y s -> do
3224 z <- fstep acc y
3225 z `seq` return $ Yield z (s, Just z)
3226 Skip s -> return $ Skip (s, Just acc)
3227 Stop -> return Stop
3229{-# INLINE scanl1' #-}
3230scanl1' :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
3231scanl1' f = scanl1M' (\x y -> return (f x y))
3233------------------------------------------------------------------------------
3234-- Stateful map/scan
3235------------------------------------------------------------------------------
3237data RollingMapState s a = RollingMapInit s | RollingMapGo s a
3239{-# INLINE rollingMapM #-}
3240rollingMapM :: Monad m => (a -> a -> m b) -> Stream m a -> Stream m b
3241rollingMapM f (Stream step1 state1) = Stream step (RollingMapInit state1)
3242 where
3243 step gst (RollingMapInit st) = do
3244 r <- step1 (adaptState gst) st
3245 return $ case r of
3246 Yield x s -> Skip $ RollingMapGo s x
3247 Skip s -> Skip $ RollingMapInit s
3248 Stop -> Stop
3250 step gst (RollingMapGo s1 x1) = do
3251 r <- step1 (adaptState gst) s1
3252 case r of
3253 Yield x s -> do
3254 !res <- f x x1
3255 return $ Yield res $ RollingMapGo s x
3256 Skip s -> return $ Skip $ RollingMapGo s x1
3257 Stop -> return $ Stop
3259{-# INLINE rollingMap #-}
3260rollingMap :: Monad m => (a -> a -> b) -> Stream m a -> Stream m b
3261rollingMap f = rollingMapM (\x y -> return $ f x y)
3263------------------------------------------------------------------------------
3264-- Tapping/Distributing
3265------------------------------------------------------------------------------
3267{-# INLINE tap #-}
3268tap :: Monad m => Fold m a b -> Stream m a -> Stream m a
3269tap (Fold fstep initial extract) (Stream step state) = Stream step' Nothing
3271 where
3273 step' _ Nothing = do
3274 r <- initial
3275 return $ Skip (Just (r, state))
3277 step' gst (Just (acc, st)) = acc `seq` do
3278 r <- step gst st
3279 case r of
3280 Yield x s -> do
3281 acc' <- fstep acc x
3282 return $ Yield x (Just (acc', s))
3283 Skip s -> return $ Skip (Just (acc, s))
3284 Stop -> do
3285 void $ extract acc
3286 return $ Stop
3288{-# INLINE_NORMAL tapOffsetEvery #-}
3289tapOffsetEvery :: Monad m
3290 => Int -> Int -> Fold m a b -> Stream m a -> Stream m a
3291tapOffsetEvery offset n (Fold fstep initial extract) (Stream step state) =
3292 Stream step' Nothing
3294 where
3296 {-# INLINE_LATE step' #-}
3297 step' _ Nothing = do
3298 r <- initial
3299 return $ Skip (Just (r, state, offset `mod` n))
3301 step' gst (Just (acc, st, count)) | count <= 0 = do
3302 r <- step gst st
3303 case r of
3304 Yield x s -> do
3305 !acc' <- fstep acc x
3306 return $ Yield x (Just (acc', s, n - 1))
3307 Skip s -> return $ Skip (Just (acc, s, count))
3308 Stop -> do
3309 void $ extract acc
3310 return $ Stop
3312 step' gst (Just (acc, st, count)) = do
3313 r <- step gst st
3314 case r of
3315 Yield x s -> return $ Yield x (Just (acc, s, count - 1))
3316 Skip s -> return $ Skip (Just (acc, s, count))
3317 Stop -> do
3318 void $ extract acc
3319 return $ Stop
3321{-# INLINE_NORMAL pollCounts #-}
3322pollCounts
3323 :: MonadAsync m
3324 => (Stream m Int -> Stream m Int)
3325 -> Fold m Int b
3326 -> Stream m a
3327 -> Stream m a
3328pollCounts transf fld (Stream step state) = Stream step' Nothing
3329 where
3331 {-# INLINE_LATE step' #-}
3332 step' _ Nothing = do
3333 countVar <- liftIO $ newVar (0 :: Int)
3334 tid <- forkManaged
3335 $ void $ runFold fld
3336 $ transf $ fromPrimVar countVar
3337 return $ Skip (Just (countVar, tid, state))
3339 step' gst (Just (countVar, tid, st)) = do
3340 r <- step gst st
3341 case r of
3342 Yield x s -> do
3343 liftIO $ modifyVar' countVar (+ 1)
3344 return $ Yield x (Just (countVar, tid, s))
3345 Skip s -> return $ Skip (Just (countVar, tid, s))
3346 Stop -> do
3347 liftIO $ killThread tid
3348 return Stop
3350{-# INLINE_NORMAL tapRate #-}
3351tapRate ::
3352 (MonadAsync m, MonadCatch m)
3353 => Double
3354 -> (Int -> m b)
3355 -> Stream m a
3356 -> Stream m a
3357tapRate samplingRate action (Stream step state) = Stream step' Nothing
3358 where
3359 {-# NOINLINE loop #-}
3360 loop countVar prev = do
3361 i <-
3362 MC.catch
3363 (do liftIO $ threadDelay (round $ samplingRate * 1000000)
3364 i <- liftIO $ readVar countVar
3365 let !diff = i - prev
3366 void $ action diff
3367 return i)
3368 (\(e :: AsyncException) -> do
3369 i <- liftIO $ readVar countVar
3370 let !diff = i - prev
3371 void $ action diff
3372 throwM (MC.toException e))
3373 loop countVar i
3375 {-# INLINE_LATE step' #-}
3376 step' _ Nothing = do
3377 countVar <- liftIO $ newVar 0
3378 tid <- fork $ loop countVar 0
3379 ref <- liftIO $ newIORef ()
3380 _ <- liftIO $ mkWeakIORef ref (killThread tid)
3381 return $ Skip (Just (countVar, tid, state, ref))
3383 step' gst (Just (countVar, tid, st, ref)) = do
3384 r <- step gst st
3385 case r of
3386 Yield x s -> do
3387 liftIO $ modifyVar' countVar (+ 1)
3388 return $ Yield x (Just (countVar, tid, s, ref))
3389 Skip s -> return $ Skip (Just (countVar, tid, s, ref))
3390 Stop -> do
3391 liftIO $ killThread tid
3392 return Stop
3395-------------------------------------------------------------------------------
3396-- Filtering
3397-------------------------------------------------------------------------------
3399{-# INLINE_NORMAL takeWhileM #-}
3400takeWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
3401takeWhileM f (Stream step state) = Stream step' state
3402 where
3403 {-# INLINE_LATE step' #-}
3404 step' gst st = do
3405 r <- step gst st
3406 case r of
3407 Yield x s -> do
3408 b <- f x
3409 return $ if b then Yield x s else Stop
3410 Skip s -> return $ Skip s
3411 Stop -> return Stop
3413{-# INLINE takeWhile #-}
3414takeWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
3415takeWhile f = takeWhileM (return . f)
3417{-# INLINE_NORMAL drop #-}
3418drop :: Monad m => Int -> Stream m a -> Stream m a
3419drop n (Stream step state) = Stream step' (state, Just n)
3420 where
3421 {-# INLINE_LATE step' #-}
3422 step' gst (st, Just i)
3423 | i > 0 = do
3424 r <- step gst st
3425 return $
3426 case r of
3427 Yield _ s -> Skip (s, Just (i - 1))
3428 Skip s -> Skip (s, Just i)
3429 Stop -> Stop
3430 | otherwise = return $ Skip (st, Nothing)
3432 step' gst (st, Nothing) = do
3433 r <- step gst st
3434 return $
3435 case r of
3436 Yield x s -> Yield x (s, Nothing)
3437 Skip s -> Skip (s, Nothing)
3438 Stop -> Stop
3440data DropWhileState s a
3441 = DropWhileDrop s
3442 | DropWhileYield a s
3443 | DropWhileNext s
3445{-# INLINE_NORMAL dropWhileM #-}
3446dropWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
3447dropWhileM f (Stream step state) = Stream step' (DropWhileDrop state)
3448 where
3449 {-# INLINE_LATE step' #-}
3450 step' gst (DropWhileDrop st) = do
3451 r <- step gst st
3452 case r of
3453 Yield x s -> do
3454 b <- f x
3455 if b
3456 then return $ Skip (DropWhileDrop s)
3457 else return $ Skip (DropWhileYield x s)
3458 Skip s -> return $ Skip (DropWhileDrop s)
3459 Stop -> return Stop
3461 step' gst (DropWhileNext st) = do
3462 r <- step gst st
3463 case r of
3464 Yield x s -> return $ Skip (DropWhileYield x s)
3465 Skip s -> return $ Skip (DropWhileNext s)
3466 Stop -> return Stop
3468 step' _ (DropWhileYield x st) = return $ Yield x (DropWhileNext st)
3470{-# INLINE dropWhile #-}
3471dropWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
3472dropWhile f = dropWhileM (return . f)
3474{-# INLINE_NORMAL filterM #-}
3475filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
3476filterM f (Stream step state) = Stream step' state
3477 where
3478 {-# INLINE_LATE step' #-}
3479 step' gst st = do
3480 r <- step gst st
3481 case r of
3482 Yield x s -> do
3483 b <- f x
3484 return $ if b
3485 then Yield x s
3486 else Skip s
3487 Skip s -> return $ Skip s
3488 Stop -> return Stop
3490{-# INLINE filter #-}
3491filter :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
3492filter f = filterM (return . f)
3494{-# INLINE_NORMAL uniq #-}
3495uniq :: (Eq a, Monad m) => Stream m a -> Stream m a
3496uniq (Stream step state) = Stream step' (Nothing, state)
3497 where
3498 {-# INLINE_LATE step' #-}
3499 step' gst (Nothing, st) = do
3500 r <- step gst st
3501 case r of
3502 Yield x s -> return $ Yield x (Just x, s)
3503 Skip s -> return $ Skip (Nothing, s)
3504 Stop -> return Stop
3505 step' gst (Just x, st) = do
3506 r <- step gst st
3507 case r of
3508 Yield y s | x == y -> return $ Skip (Just x, s)
3509 | otherwise -> return $ Yield y (Just y, s)
3510 Skip s -> return $ Skip (Just x, s)
3511 Stop -> return Stop
3513------------------------------------------------------------------------------
3514-- Transformation by Mapping
3515------------------------------------------------------------------------------
3517{-# INLINE_NORMAL sequence #-}
3518sequence :: Monad m => Stream m (m a) -> Stream m a
3519sequence (Stream step state) = Stream step' state
3520 where
3521 {-# INLINE_LATE step' #-}
3522 step' gst st = do
3523 r <- step (adaptState gst) st
3524 case r of
3525 Yield x s -> x >>= \a -> return (Yield a s)
3526 Skip s -> return $ Skip s
3527 Stop -> return Stop
3529------------------------------------------------------------------------------
3530-- Inserting
3531------------------------------------------------------------------------------
3533data LoopState x s = FirstYield s
3534 | InterspersingYield s
3535 | YieldAndCarry x s
3537{-# INLINE_NORMAL intersperseM #-}
3538intersperseM :: Monad m => m a -> Stream m a -> Stream m a
3539intersperseM m (Stream step state) = Stream step' (FirstYield state)
3540 where
3541 {-# INLINE_LATE step' #-}
3542 step' gst (FirstYield st) = do
3543 r <- step gst st
3544 return $
3545 case r of
3546 Yield x s -> Skip (YieldAndCarry x s)
3547 Skip s -> Skip (FirstYield s)
3548 Stop -> Stop
3550 step' gst (InterspersingYield st) = do
3551 r <- step gst st
3552 case r of
3553 Yield x s -> do
3554 a <- m
3555 return $ Yield a (YieldAndCarry x s)
3556 Skip s -> return $ Skip $ InterspersingYield s
3557 Stop -> return Stop
3559 step' _ (YieldAndCarry x st) = return $ Yield x (InterspersingYield st)
3561data SuffixState s a
3562 = SuffixElem s
3563 | SuffixSuffix s
3564 | SuffixYield a (SuffixState s a)
3566{-# INLINE_NORMAL intersperseSuffix #-}
3567intersperseSuffix :: forall m a. Monad m => m a -> Stream m a -> Stream m a
3568intersperseSuffix action (Stream step state) = Stream step' (SuffixElem state)
3569 where
3570 {-# INLINE_LATE step' #-}
3571 step' gst (SuffixElem st) = do
3572 r <- step gst st
3573 return $ case r of
3574 Yield x s -> Skip (SuffixYield x (SuffixSuffix s))
3575 Skip s -> Skip (SuffixElem s)
3576 Stop -> Stop
3578 step' _ (SuffixSuffix st) = do
3579 action >>= \r -> return $ Skip (SuffixYield r (SuffixElem st))
3581 step' _ (SuffixYield x next) = return $ Yield x next
3583data SuffixSpanState s a
3584 = SuffixSpanElem s Int
3585 | SuffixSpanSuffix s
3586 | SuffixSpanYield a (SuffixSpanState s a)
3587 | SuffixSpanLast
3588 | SuffixSpanStop
3590-- | intersperse after every n items
3591{-# INLINE_NORMAL intersperseSuffixBySpan #-}
3592intersperseSuffixBySpan :: forall m a. Monad m
3593 => Int -> m a -> Stream m a -> Stream m a
3594intersperseSuffixBySpan n action (Stream step state) =
3595 Stream step' (SuffixSpanElem state n)
3596 where
3597 {-# INLINE_LATE step' #-}
3598 step' gst (SuffixSpanElem st i) | i > 0 = do
3599 r <- step gst st
3600 return $ case r of
3601 Yield x s -> Skip (SuffixSpanYield x (SuffixSpanElem s (i - 1)))
3602 Skip s -> Skip (SuffixSpanElem s i)
3603 Stop -> if i == n then Stop else Skip SuffixSpanLast
3604 step' _ (SuffixSpanElem st _) = return $ Skip (SuffixSpanSuffix st)
3606 step' _ (SuffixSpanSuffix st) = do
3607 action >>= \r -> return $ Skip (SuffixSpanYield r (SuffixSpanElem st n))
3609 step' _ (SuffixSpanLast) = do
3610 action >>= \r -> return $ Skip (SuffixSpanYield r SuffixSpanStop)
3612 step' _ (SuffixSpanYield x next) = return $ Yield x next
3614 step' _ (SuffixSpanStop) = return Stop
3616{-# INLINE intersperse #-}
3617intersperse :: Monad m => a -> Stream m a -> Stream m a
3618intersperse a = intersperseM (return a)
3620{-# INLINE_NORMAL insertBy #-}
3621insertBy :: Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
3622insertBy cmp a (Stream step state) = Stream step' (state, False, Nothing)
3623 where
3624 {-# INLINE_LATE step' #-}
3625 step' gst (st, False, _) = do
3626 r <- step gst st
3627 case r of
3628 Yield x s -> case cmp a x of
3629 GT -> return $ Yield x (s, False, Nothing)
3630 _ -> return $ Yield a (s, True, Just x)
3631 Skip s -> return $ Skip (s, False, Nothing)
3632 Stop -> return $ Yield a (st, True, Nothing)
3634 step' _ (_, True, Nothing) = return Stop
3636 step' gst (st, True, Just prev) = do
3637 r <- step gst st
3638 case r of
3639 Yield x s -> return $ Yield prev (s, True, Just x)
3640 Skip s -> return $ Skip (s, True, Just prev)
3641 Stop -> return $ Yield prev (st, True, Nothing)
3643------------------------------------------------------------------------------
3644-- Deleting
3645------------------------------------------------------------------------------
3647{-# INLINE_NORMAL deleteBy #-}
3648deleteBy :: Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a
3649deleteBy eq x (Stream step state) = Stream step' (state, False)
3650 where
3651 {-# INLINE_LATE step' #-}
3652 step' gst (st, False) = do
3653 r <- step gst st
3654 case r of
3655 Yield y s -> return $
3656 if eq x y then Skip (s, True) else Yield y (s, False)
3657 Skip s -> return $ Skip (s, False)
3658 Stop -> return Stop
3660 step' gst (st, True) = do
3661 r <- step gst st
3662 case r of
3663 Yield y s -> return $ Yield y (s, True)
3664 Skip s -> return $ Skip (s, True)
3665 Stop -> return Stop
3667------------------------------------------------------------------------------
3668-- Transformation by Map and Filter
3669------------------------------------------------------------------------------
3671-- XXX Will this always fuse properly?
3672{-# INLINE_NORMAL mapMaybe #-}
3673mapMaybe :: Monad m => (a -> Maybe b) -> Stream m a -> Stream m b
3674mapMaybe f = fmap fromJust . filter isJust . map f
3676{-# INLINE_NORMAL mapMaybeM #-}
3677mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b
3678mapMaybeM f = fmap fromJust . filter isJust . mapM f
3680------------------------------------------------------------------------------
3681-- Zipping
3682------------------------------------------------------------------------------
3684{-# INLINE_NORMAL indexed #-}
3685indexed :: Monad m => Stream m a -> Stream m (Int, a)
3686indexed (Stream step state) = Stream step' (state, 0)
3687 where
3688 {-# INLINE_LATE step' #-}
3689 step' gst (st, i) = i `seq` do
3690 r <- step (adaptState gst) st
3691 case r of
3692 Yield x s -> return $ Yield (i, x) (s, i+1)
3693 Skip s -> return $ Skip (s, i)
3694 Stop -> return Stop
3696{-# INLINE_NORMAL indexedR #-}
3697indexedR :: Monad m => Int -> Stream m a -> Stream m (Int, a)
3698indexedR m (Stream step state) = Stream step' (state, m)
3699 where
3700 {-# INLINE_LATE step' #-}
3701 step' gst (st, i) = i `seq` do
3702 r <- step (adaptState gst) st
3703 case r of
3704 Yield x s -> let i' = i - 1
3705 in return $ Yield (i, x) (s, i')
3706 Skip s -> return $ Skip (s, i)
3707 Stop -> return Stop
3709{-# INLINE_NORMAL zipWithM #-}
3710zipWithM :: Monad m
3711 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
3712zipWithM f (Stream stepa ta) (Stream stepb tb) = Stream step (ta, tb, Nothing)
3713 where
3714 {-# INLINE_LATE step #-}
3715 step gst (sa, sb, Nothing) = do
3716 r <- stepa (adaptState gst) sa
3717 return $
3718 case r of
3719 Yield x sa' -> Skip (sa', sb, Just x)
3720 Skip sa' -> Skip (sa', sb, Nothing)
3721 Stop -> Stop
3723 step gst (sa, sb, Just x) = do
3724 r <- stepb (adaptState gst) sb
3725 case r of
3726 Yield y sb' -> do
3727 z <- f x y
3728 return $ Yield z (sa, sb', Nothing)
3729 Skip sb' -> return $ Skip (sa, sb', Just x)
3730 Stop -> return Stop
3732#if __GLASGOW_HASKELL__ >= 801
3733{-# RULES "zipWithM xs xs"
3734 forall f xs. zipWithM @Identity f xs xs = mapM (\x -> f x x) xs #-}
3735#endif
3737{-# INLINE zipWith #-}
3738zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
3739zipWith f = zipWithM (\a b -> return (f a b))
3741-- | Like 'zipWithM' but zips concurrently i.e. both the streams being zipped
3742-- are generated concurrently.
3744{-# INLINE_NORMAL zipAsyncWithM #-}
3745zipAsyncWithM :: MonadAsync m
3746 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
3747zipAsyncWithM f m1 m2 = Stream step Nothing
3749 where
3751 {-# INLINE_LATE step #-}
3752 step gst Nothing = do
3753 ma <- mkParallel (adaptState gst) m1
3754 mb <- mkParallel (adaptState gst) m2
3755 return $ Skip (Just $ zipWithM f ma mb)
3757 step gst (Just (UnStream step1 st)) = do
3758 r <- step1 gst st
3759 return $ case r of
3760 Yield a s -> Yield a (Just $ Stream step1 s)
3761 Skip s -> Skip (Just $ Stream step1 s)
3762 Stop -> Stop
3764-- | Like 'zipWith' but zips concurrently i.e. both the streams being zipped
3765-- are generated concurrently.
3767{-# INLINE zipAsyncWith #-}
3768zipAsyncWith :: MonadAsync m
3769 => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
3770zipAsyncWith f = zipAsyncWithM (\a b -> return (f a b))
3772------------------------------------------------------------------------------
3773-- Merging
3774------------------------------------------------------------------------------
3776{-# INLINE_NORMAL mergeByM #-}
3777mergeByM
3778 :: (Monad m)
3779 => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
3780mergeByM cmp (Stream stepa ta) (Stream stepb tb) =
3781 Stream step (Just ta, Just tb, Nothing, Nothing)
3782 where
3783 {-# INLINE_LATE step #-}
3785 -- one of the values is missing, and the corresponding stream is running
3786 step gst (Just sa, sb, Nothing, b) = do
3787 r <- stepa gst sa
3788 return $ case r of
3789 Yield a sa' -> Skip (Just sa', sb, Just a, b)
3790 Skip sa' -> Skip (Just sa', sb, Nothing, b)
3791 Stop -> Skip (Nothing, sb, Nothing, b)
3793 step gst (sa, Just sb, a, Nothing) = do
3794 r <- stepb gst sb
3795 return $ case r of
3796 Yield b sb' -> Skip (sa, Just sb', a, Just b)
3797 Skip sb' -> Skip (sa, Just sb', a, Nothing)
3798 Stop -> Skip (sa, Nothing, a, Nothing)
3800 -- both the values are available
3801 step _ (sa, sb, Just a, Just b) = do
3802 res <- cmp a b
3803 return $ case res of
3804 GT -> Yield b (sa, sb, Just a, Nothing)
3805 _ -> Yield a (sa, sb, Nothing, Just b)
3807 -- one of the values is missing, corresponding stream is done
3808 step _ (Nothing, sb, Nothing, Just b) =
3809 return $ Yield b (Nothing, sb, Nothing, Nothing)
3811 step _ (sa, Nothing, Just a, Nothing) =
3812 return $ Yield a (sa, Nothing, Nothing, Nothing)
3814 step _ (Nothing, Nothing, Nothing, Nothing) = return Stop
3816{-# INLINE mergeBy #-}
3817mergeBy
3818 :: (Monad m)
3819 => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
3820mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
3822------------------------------------------------------------------------------
3823-- Transformation comprehensions
3824------------------------------------------------------------------------------
3826{-# INLINE_NORMAL the #-}
3827the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
3828the (Stream step state) = go state
3829 where
3830 go st = do
3831 r <- step defState st
3832 case r of
3833 Yield x s -> go' x s
3834 Skip s -> go s
3835 Stop -> return Nothing
3836 go' n st = do
3837 r <- step defState st
3838 case r of
3839 Yield x s | x == n -> go' n s
3840 | otherwise -> return Nothing
3841 Skip s -> go' n s
3842 Stop -> return (Just n)
3844{-# INLINE runFold #-}
3845runFold :: (Monad m) => Fold m a b -> Stream m a -> m b
3846runFold (Fold step begin done) = foldlMx' step begin done
3848-------------------------------------------------------------------------------
3849-- Concurrent application and fold
3850-------------------------------------------------------------------------------
3852-- Using StreamD the worker stream producing code can fuse with the code to
3853-- queue output to the SVar giving some perf boost.
3855-- Note that StreamD can only be used in limited situations, specifically, we
3856-- cannot implement joinStreamVarPar using this.
3858-- XXX make sure that the SVar passed is a Parallel style SVar.
3860-- | Fold the supplied stream to the SVar asynchronously using Parallel
3861-- concurrency style.
3862-- {-# INLINE_NORMAL toSVarParallel #-}
3863{-# INLINE toSVarParallel #-}
3864toSVarParallel :: MonadAsync m
3865 => State t m a -> SVar t m a -> Stream m a -> m ()
3866toSVarParallel st sv xs =
3867 if svarInspectMode sv
3868 then forkWithDiag
3869 else do
3870 tid <-
3871 case getYieldLimit st of
3872 Nothing -> doFork (work Nothing)
3873 (svarMrun sv)
3874 (handleChildException sv)
3875 Just _ -> doFork (workLim Nothing)
3876 (svarMrun sv)
3877 (handleChildException sv)
3878 modifyThread sv tid
3880 where
3882 {-# NOINLINE work #-}
3883 work info = (runFold (FL.toParallelSVar sv info) xs)
3885 {-# NOINLINE workLim #-}
3886 workLim info = runFold (FL.toParallelSVarLimited sv info) xs
3888 {-# NOINLINE forkWithDiag #-}
3889 forkWithDiag = do
3890 -- We do not use workerCount in case of ParallelVar but still there is
3891 -- no harm in maintaining it correctly.
3892 liftIO $ atomicModifyIORefCAS_ (workerCount sv) $ \n -> n + 1
3893 recordMaxWorkers sv
3894 -- This allocation matters when significant number of workers are being
3895 -- sent. We allocate it only when needed. The overhead increases by 4x.
3896 winfo <-
3897 case yieldRateInfo sv of
3898 Nothing -> return Nothing
3899 Just _ -> liftIO $ do
3900 cntRef <- newIORef 0
3901 t <- getTime Monotonic
3902 lat <- newIORef (0, t)
3903 return $ Just WorkerInfo
3904 { workerYieldMax = 0
3905 , workerYieldCount = cntRef
3906 , workerLatencyStart = lat
3908 tid <-
3909 case getYieldLimit st of
3910 Nothing -> doFork (work winfo)
3911 (svarMrun sv)
3912 (handleChildException sv)
3913 Just _ -> doFork (workLim winfo)
3914 (svarMrun sv)
3915 (handleChildException sv)
3916 modifyThread sv tid
3918{-# INLINE_NORMAL mkParallel #-}
3919mkParallel :: MonadAsync m => State t m a -> Stream m a -> m (Stream m a)
3920mkParallel st m = do
3921 sv <- newParallelVar StopNone defState
3922 toSVarParallel st sv m
3923 return $ fromSVar sv
3925{-# INLINE_NORMAL applyParallel #-}
3926applyParallel :: MonadAsync m
3927 => (Stream m a -> Stream m b) -> Stream m a -> Stream m b
3928applyParallel f m = Stream step Nothing
3929 where
3931 {-# INLINE_LATE step #-}
3932 step gst Nothing = do
3933 sv <- newParallelVar StopNone (adaptState gst)
3934 toSVarParallel (adaptState gst) sv m
3935 return $ Skip $ Just $ f (fromSVar sv)
3937 step gst (Just (UnStream step1 st)) = do
3938 r <- step1 gst st
3939 return $ case r of
3940 Yield a s -> Yield a (Just $ Stream step1 s)
3941 Skip s -> Skip (Just $ Stream step1 s)
3942 Stop -> Stop
3944{-# INLINE foldParallel #-}
3945foldParallel :: (K.IsStream t, MonadAsync m) => (t m a -> m b) -> t m a -> m b
3946foldParallel f m = do
3947 sv <- newParallelVar StopNone defState
3948 toSVarParallel defState sv (toStreamD m)
3949 f $ fromStreamD $ fromSVar sv
3951-------------------------------------------------------------------------------
3952-- Concurrent tap
3953-------------------------------------------------------------------------------
3955-- | Create an SVar with a fold consumer that will fold any elements sent to it
3956-- using the supplied fold function.
3957{-# INLINE newFoldSVar #-}
3958newFoldSVar :: MonadAsync m => State t m a -> Fold m a b -> m (SVar t m a)
3959newFoldSVar stt f = do
3960 -- Buffer size for the SVar is derived from the current state
3961 sv <- newParallelVar StopAny (adaptState stt)
3962 -- Add the producer thread-id to the SVar.
3963 liftIO myThreadId >>= modifyThread sv
3964 void $ doFork (work sv) (svarMrun sv) (handleFoldException sv)
3965 return sv
3967 where
3969 {-# NOINLINE work #-}
3970 work sv = void $ runFold f $ fromProducer sv
3972data TapState sv st = TapInit | Tapping sv st | TapDone st
3974{-# INLINE_NORMAL tapAsync #-}
3975tapAsync :: MonadAsync m => Fold m a b -> Stream m a -> Stream m a
3976tapAsync f (Stream step1 state1) = Stream step TapInit
3977 where
3979 drainFold svr = do
3980 -- In general, a Stop event would come equipped with the result
3981 -- of the fold. It is not used here but it would be useful in
3982 -- applicative and distribute.
3983 done <- fromConsumer svr
3984 when (not done) $ do
3985 liftIO $ withDiagMVar svr "teeToSVar: waiting to drain"
3986 $ takeMVar (outputDoorBellFromConsumer svr)
3987 drainFold svr
3989 stopFold svr = do
3990 liftIO $ sendStop svr Nothing
3991 -- drain/wait until a stop event arrives from the fold.
3992 drainFold svr
3994 {-# INLINE_LATE step #-}
3995 step gst TapInit = do
3996 sv <- newFoldSVar gst f
3997 return $ Skip (Tapping sv state1)
3999 step gst (Tapping sv st) = do
4000 r <- step1 gst st
4001 case r of
4002 Yield a s -> do
4003 done <- pushToFold sv a
4004 if done
4005 then do
4006 -- XXX we do not need to wait synchronously here
4007 stopFold sv
4008 return $ Yield a (TapDone s)
4009 else return $ Yield a (Tapping sv s)
4010 Skip s -> return $ Skip (Tapping sv s)
4011 Stop -> do
4012 stopFold sv
4013 return $ Stop
4015 step gst (TapDone st) = do
4016 r <- step1 gst st
4017 return $ case r of
4018 Yield a s -> Yield a (TapDone s)
4019 Skip s -> Skip (TapDone s)
4020 Stop -> Stop
4022-- XXX Is there room for improvement?
4023-- | Take last 'n' elements from the stream and discard the rest.
4024{-# INLINABLE lastN #-}
4025lastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
4026lastN n = Fold step initial done
4027 where
4028 step (Tuple3' rb rh i) a = do
4029 rh1 <- liftIO $ RB.unsafeInsert rb rh a
4030 return $ Tuple3' rb rh1 (i + 1)
4031 initial = fmap (\(a, b) -> Tuple3' a b 0) $ liftIO $ RB.new n
4032 done (Tuple3' rb rh i) = do
4033 arr <- liftIO $ A.newArray n
4034 foldFunc i rh snoc' arr rb
4035 snoc' b a = liftIO $ A.unsafeSnoc b a
4036 foldFunc i
4037 | i < n = RB.unsafeFoldRingM
4038 | otherwise = RB.unsafeFoldRingFullM