Copyright | (c) 2018 Composewell Technologies |
---|---|
License | BSD-3-Clause |
Maintainer | streamly@composewell.com |
Stability | experimental |
Portability | GHC |
Safe Haskell | None |
Language | Haskell2010 |
Streamly.Internal.Data.Stream
Description
Direct style re-implementation of CPS stream in Streamly.Internal.Data.StreamK. GHC is able to INLINE and fuse direct style better, providing better performance than CPS implementation.
import qualified Streamly.Internal.Data.Stream as Stream
Synopsis
- concat :: forall (m :: Type -> Type) a. Monad m => Stream m (Stream m a) -> Stream m a
- foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b
- head :: Monad m => Stream m a -> m (Maybe a)
- foldl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> m b
- mapM :: Monad m => (a -> m b) -> Stream m a -> Stream m b
- map :: forall (m :: Type -> Type) a b. Monad m => (a -> b) -> Stream m a -> Stream m b
- loop :: forall (m :: Type -> Type) b a. Monad m => Stream m b -> Stream m a -> Stream m (a, b)
- fromList :: forall (m :: Type -> Type) a. Applicative m => [a] -> Stream m a
- toList :: Monad m => Stream m a -> m [a]
- uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
- takeWhile :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a
- take :: forall (m :: Type -> Type) a. Applicative m => Int -> Stream m a -> Stream m a
- splitAt :: String -> Int -> [a] -> ([a], [a])
- concatMap :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b) -> Stream m a -> Stream m b
- zipWith :: forall (m :: Type -> Type) a b c. Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
- fold :: Monad m => Fold m a b -> Stream m a -> m b
- foldrM :: Monad m => (a -> m b -> m b) -> m b -> Stream m a -> m b
- data Stream (m :: Type -> Type) a where
- zipWithM :: Monad m => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
- unfold :: forall (m :: Type -> Type) a b. Applicative m => Unfold m a b -> a -> Stream m b
- append :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- data Step s a
- fromPure :: forall (m :: Type -> Type) a. Applicative m => a -> Stream m a
- toStreamK :: forall (m :: Type -> Type) a. Monad m => Stream m a -> StreamK m a
- foldBreak :: Monad m => Fold m a b -> Stream m a -> m (b, Stream m a)
- foldEither :: Monad m => Fold m a b -> Stream m a -> m (Either (Fold m a b) (b, Stream m a))
- nilM :: Applicative m => m b -> Stream m a
- consM :: Applicative m => m a -> Stream m a -> Stream m a
- fromStreamK :: forall (m :: Type -> Type) a. Applicative m => StreamK m a -> Stream m a
- foldMany :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b
- takeEndBy :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a
- takeEndBy_ :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a
- refoldMany :: Monad m => Refold m x a b -> m x -> Stream m a -> Stream m b
- groupsOf :: forall (m :: Type -> Type) a b. Monad m => Int -> Fold m a b -> Stream m a -> Stream m b
- drain :: Monad m => Stream m a -> m ()
- foldlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> m b
- fromEffect :: Applicative m => m a -> Stream m a
- takeWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
- crossWith :: forall (m :: Type -> Type) a b c. Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
- cross :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> Stream m b -> Stream m (a, b)
- fairCross :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> Stream m b -> Stream m (a, b)
- unfoldEach :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b
- concatEffect :: Monad m => m (Stream m a) -> Stream m a
- concatMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b
- concatFor :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> (a -> Stream m b) -> Stream m b
- concatForM :: Monad m => Stream m a -> (a -> m (Stream m b)) -> Stream m b
- eqBy :: Monad m => (a -> b -> Bool) -> Stream m a -> Stream m b -> m Bool
- cmpBy :: Monad m => (a -> b -> Ordering) -> Stream m a -> Stream m b -> m Ordering
- unfoldMany :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b
- newtype Nested (m :: Type -> Type) a = Nested {}
- foldrS :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b -> Stream m b) -> Stream m b -> Stream m a -> Stream m b
- foldAddLazy :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Fold m a b
- foldAdd :: Monad m => Fold m a b -> Stream m a -> m (Fold m a b)
- foldlx' :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> m b
- foldlMx' :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> m b
- foldrMx :: Monad m => (a -> m x -> m x) -> m x -> (m x -> m b) -> Stream m a -> m b
- headElse :: Monad m => a -> Stream m a -> m a
- takeEndByM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
- data AppendState s1 s2
- = AppendFirst s1
- | AppendSecond s2
- crossApply :: forall (f :: Type -> Type) a b. Functor f => Stream f (a -> b) -> Stream f a -> Stream f b
- crossApplyFst :: forall (f :: Type -> Type) a b. Functor f => Stream f a -> Stream f b -> Stream f a
- crossApplySnd :: forall (f :: Type -> Type) a b. Functor f => Stream f a -> Stream f b -> Stream f b
- data FairUnfoldState o i
- = FairUnfoldInit o ([i] -> [i])
- | FairUnfoldNext o ([i] -> [i]) [i]
- | FairUnfoldDrain ([i] -> [i]) [i]
- fairCrossWithM :: Monad m => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
- fairCrossWith :: forall (m :: Type -> Type) a b c. Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
- loopBy :: forall (m :: Type -> Type) x b a. Monad m => Unfold m x b -> x -> Stream m a -> Stream m (a, b)
- data ConcatMapUState o i
- = ConcatMapUOuter o
- | ConcatMapUInner o i
- unfoldCross :: forall (m :: Type -> Type) a b c. Monad m => Unfold m (a, b) c -> Stream m a -> Stream m b -> Stream m c
- unfoldIterate :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a
- bfsUnfoldIterate :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a
- altBfsUnfoldIterate :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a
- concatIterateScan :: Monad m => (b -> a -> m b) -> (b -> m (Maybe (b, Stream m a))) -> b -> Stream m a
- concatIterate :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a
- bfsConcatIterate :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a
- altBfsConcatIterate :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a
- data FoldMany s fs b a
- = FoldManyStart s
- | FoldManyFirst fs s
- | FoldManyLoop s fs
- | FoldManyYield b (FoldMany s fs b a)
- | FoldManyDone
- data FoldManyPost s fs b a
- = FoldManyPostStart s
- | FoldManyPostLoop s fs
- | FoldManyPostYield b (FoldManyPost s fs b a)
- | FoldManyPostDone
- foldManyPost :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b
- foldManySepBy :: forall (m :: Type -> Type) a b. Fold m a b -> Fold m a b -> Stream m a -> Stream m b
- refoldIterateM :: Monad m => Refold m b a b -> m b -> Stream m a -> Stream m b
- bfsReduceIterate :: Monad m => (a -> a -> m a) -> Stream m a -> m (Maybe a)
- bfsFoldIterate :: Fold m a (Either a a) -> Stream m a -> m (Maybe a)
- indexEndBy :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int)
- indexEndBy_ :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int)
- sliceOnSuffix :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int)
- indexOnSuffix :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int)
- type CrossStream = Nested
- mkCross :: forall (m :: Type -> Type) a. Stream m a -> Nested m a
- unCross :: forall (m :: Type -> Type) a. Nested m a -> Stream m a
- reduceIterateBfs :: Monad m => (a -> a -> m a) -> Stream m a -> m (Maybe a)
- unfoldIterateDfs :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a
- unfoldIterateBfs :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a
- unfoldIterateBfsRev :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a
- concatIterateDfs :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a
- concatIterateBfs :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a
- concatIterateBfsRev :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a
- repeat :: forall (m :: Type -> Type) a. Monad m => a -> Stream m a
- unfoldr :: forall (m :: Type -> Type) s a. Monad m => (s -> Maybe (a, s)) -> s -> Stream m a
- iterate :: forall (m :: Type -> Type) a. Monad m => (a -> a) -> a -> Stream m a
- replicate :: forall (m :: Type -> Type) a. Monad m => Int -> a -> Stream m a
- replicateM :: Monad m => Int -> m a -> Stream m a
- cons :: forall (m :: Type -> Type) a. Applicative m => a -> Stream m a -> Stream m a
- timeout :: AbsTime -> t m ()
- times :: forall (m :: Type -> Type). MonadIO m => Stream m (AbsTime, RelTime64)
- nil :: forall (m :: Type -> Type) a. Applicative m => Stream m a
- repeatM :: Monad m => m a -> Stream m a
- fromIndices :: forall (m :: Type -> Type) a. Monad m => (Int -> a) -> Stream m a
- fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
- iterateM :: Monad m => (a -> m a) -> m a -> Stream m a
- fromListM :: Monad m => [m a] -> Stream m a
- fromPtr :: forall (m :: Type -> Type) a. (Monad m, Storable a) => Ptr a -> Stream m a
- unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
- class Enum a => Enumerable a where
- enumerateFrom :: forall (m :: Type -> Type). Monad m => a -> Stream m a
- enumerateFromTo :: forall (m :: Type -> Type). Monad m => a -> a -> Stream m a
- enumerateFromThen :: forall (m :: Type -> Type). Monad m => a -> a -> Stream m a
- enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => a -> a -> a -> Stream m a
- enumerate :: forall (m :: Type -> Type) a. (Monad m, Bounded a, Enumerable a) => Stream m a
- enumerateTo :: forall (m :: Type -> Type) a. (Monad m, Bounded a, Enumerable a) => a -> Stream m a
- fromFoldable :: forall (m :: Type -> Type) f a. (Monad m, Foldable f) => f a -> Stream m a
- enumerateFromStepNum :: forall (m :: Type -> Type) a. (Monad m, Num a) => a -> a -> Stream m a
- enumerateFromNum :: forall (m :: Type -> Type) a. (Monad m, Num a) => a -> Stream m a
- enumerateFromThenNum :: forall (m :: Type -> Type) a. (Monad m, Num a) => a -> a -> Stream m a
- enumerateFromBounded :: forall (m :: Type -> Type) a. (Monad m, Enumerable a, Bounded a) => a -> Stream m a
- enumerateFromToSmall :: forall (m :: Type -> Type) a. (Monad m, Enum a) => a -> a -> Stream m a
- enumerateFromThenToSmall :: forall (m :: Type -> Type) a. (Monad m, Enum a) => a -> a -> a -> Stream m a
- enumerateFromThenSmallBounded :: forall (m :: Type -> Type) a. (Monad m, Enumerable a, Bounded a) => a -> a -> Stream m a
- enumerateFromIntegral :: forall (m :: Type -> Type) a. (Monad m, Integral a, Bounded a) => a -> Stream m a
- enumerateFromThenIntegral :: forall (m :: Type -> Type) a. (Monad m, Integral a, Bounded a) => a -> a -> Stream m a
- enumerateFromToIntegral :: forall (m :: Type -> Type) a. (Monad m, Integral a) => a -> a -> Stream m a
- enumerateFromThenToIntegral :: forall (m :: Type -> Type) a. (Monad m, Integral a) => a -> a -> a -> Stream m a
- enumerateFromStepIntegral :: forall a (m :: Type -> Type). (Integral a, Monad m) => a -> a -> Stream m a
- enumerateFromFractional :: forall (m :: Type -> Type) a. (Monad m, Fractional a) => a -> Stream m a
- enumerateFromToFractional :: forall (m :: Type -> Type) a. (Monad m, Fractional a, Ord a) => a -> a -> Stream m a
- enumerateFromThenFractional :: forall (m :: Type -> Type) a. (Monad m, Fractional a) => a -> a -> Stream m a
- enumerateFromThenToFractional :: forall (m :: Type -> Type) a. (Monad m, Fractional a, Ord a) => a -> a -> a -> Stream m a
- timesWith :: forall (m :: Type -> Type). MonadIO m => Double -> Stream m (AbsTime, RelTime64)
- absTimes :: forall (m :: Type -> Type). MonadIO m => Stream m AbsTime
- absTimesWith :: forall (m :: Type -> Type). MonadIO m => Double -> Stream m AbsTime
- relTimes :: forall (m :: Type -> Type). MonadIO m => Stream m RelTime64
- relTimesWith :: forall (m :: Type -> Type). MonadIO m => Double -> Stream m RelTime64
- durations :: Double -> t m RelTime64
- generate :: forall (m :: Type -> Type) a. Monad m => Int -> (Int -> a) -> Stream m a
- generateM :: Monad m => Int -> (Int -> m a) -> Stream m a
- fromFoldableM :: (Monad m, Foldable f) => f (m a) -> Stream m a
- fromPtrN :: forall (m :: Type -> Type) a. (Monad m, Storable a) => Int -> Ptr a -> Stream m a
- fromCString# :: forall (m :: Type -> Type). Monad m => Addr# -> Stream m Word8
- fromW16CString# :: forall (m :: Type -> Type). Monad m => Addr# -> Stream m Word16
- fromByteStr# :: forall (m :: Type -> Type). Monad m => Addr# -> Stream m Word8
- maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
- minimumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
- mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
- uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
- tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
- last :: Monad m => Stream m a -> m (Maybe a)
- init :: Monad m => Stream m a -> m (Maybe (Stream m a))
- null :: Monad m => Stream m a -> m Bool
- foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
- maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
- minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
- any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
- all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
- elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
- notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
- lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
- (!!) :: Monad m => Stream m a -> Int -> m (Maybe a)
- find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
- stripPrefix :: (Monad m, Eq a) => Stream m a -> Stream m a -> m (Maybe (Stream m a))
- isPrefixOf :: (Monad m, Eq a) => Stream m a -> Stream m a -> m Bool
- isSuffixOf :: (Monad m, Eq a) => Stream m a -> Stream m a -> m Bool
- isInfixOf :: (MonadIO m, Eq a, Enum a, Unbox a) => Stream m a -> Stream m a -> m Bool
- isSubsequenceOf :: (Monad m, Eq a) => Stream m a -> Stream m a -> m Bool
- the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
- stripSuffix :: (Monad m, Eq a) => Stream m a -> Stream m a -> m (Maybe (Stream m a))
- parseD :: Monad m => Parser a m b -> Stream m a -> m (Either ParseError b)
- parseBreak :: Monad m => Parser a m b -> Stream m a -> m (Either ParseError b, Stream m a)
- parseBreakPos :: Monad m => Parser a m b -> Stream m a -> m (Either ParseErrorPos b, Stream m a)
- parse :: Monad m => Parser a m b -> Stream m a -> m (Either ParseError b)
- parsePos :: Monad m => Parser a m b -> Stream m a -> m (Either ParseErrorPos b)
- findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
- toListRev :: Monad m => Stream m a -> m [a]
- isSuffixOfUnbox :: (MonadIO m, Eq a, Unbox a) => Stream m a -> Stream m a -> m Bool
- stripSuffixUnbox :: (MonadIO m, Eq a, Unbox a) => Stream m a -> Stream m a -> m (Maybe (Stream m a))
- parseBreakD :: Monad m => Parser a m b -> Stream m a -> m (Either ParseError b, Stream m a)
- onException :: MonadCatch m => m b -> Stream m a -> Stream m a
- handle :: (MonadCatch m, Exception e) => (e -> m (Stream m a)) -> Stream m a -> Stream m a
- withAcquireIO :: forall (m :: Type -> Type) a. (MonadIO m, MonadCatch m) => (AcquireIO -> Stream m a) -> Stream m a
- bracketIO :: forall (m :: Type -> Type) b c a. (MonadIO m, MonadCatch m) => IO b -> (b -> IO c) -> (b -> Stream m a) -> Stream m a
- gbracket_ :: Monad m => m c -> (c -> m d) -> (c -> e -> Stream m b -> m (Stream m b)) -> (forall s. m s -> m (Either e s)) -> (c -> Stream m b) -> Stream m b
- before :: Monad m => m b -> Stream m a -> Stream m a
- afterIO :: forall (m :: Type -> Type) b a. MonadIO m => IO b -> Stream m a -> Stream m a
- finallyIO :: forall (m :: Type -> Type) b a. (MonadIO m, MonadCatch m) => IO b -> Stream m a -> Stream m a
- finallyIO' :: forall (m :: Type -> Type) b a. MonadIO m => AcquireIO -> IO b -> Stream m a -> Stream m a
- finallyIO'' :: forall (m :: Type -> Type) b a. (MonadIO m, MonadCatch m) => AcquireIO -> IO b -> Stream m a -> Stream m a
- bracketIO' :: forall (m :: Type -> Type) b c a. MonadIO m => AcquireIO -> IO b -> (b -> IO c) -> (b -> Stream m a) -> Stream m a
- bracketIO'' :: forall (m :: Type -> Type) b c a. (MonadIO m, MonadCatch m) => AcquireIO -> IO b -> (b -> IO c) -> (b -> Stream m a) -> Stream m a
- bracketIO3 :: forall (m :: Type -> Type) b c d e a. (MonadIO m, MonadCatch m) => IO b -> (b -> IO c) -> (b -> IO d) -> (b -> IO e) -> (b -> Stream m a) -> Stream m a
- afterUnsafe :: Monad m => m b -> Stream m a -> Stream m a
- finallyUnsafe :: MonadCatch m => m b -> Stream m a -> Stream m a
- gbracket :: MonadIO m => IO c -> (c -> IO d1) -> (c -> e -> Stream m b -> IO (Stream m b)) -> (c -> IO d2) -> (forall s. m s -> m (Either e s)) -> (c -> Stream m b) -> Stream m b
- bracketUnsafe :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
- withAcquireIO' :: forall (m :: Type -> Type) a. AcquireIO -> (AcquireIO -> Stream m a) -> Stream m a
- ghandle :: (MonadCatch m, Exception e) => (e -> Stream m a -> m (Stream m a)) -> Stream m a -> Stream m a
- morphInner :: Monad n => (forall x. m x -> n x) -> Stream m a -> Stream n a
- generalizeInner :: forall (m :: Type -> Type) a. Monad m => Stream Identity a -> Stream m a
- liftInnerWith :: Monad (t m) => (forall b. m b -> t m b) -> Stream m a -> Stream (t m) a
- runInnerWith :: Monad m => (forall b. t m b -> m b) -> Stream (t m) a -> Stream m a
- runInnerWithState :: Monad m => (forall b. s -> t m b -> m (b, s)) -> m s -> Stream (t m) a -> Stream m (s, a)
- runStateT :: Monad m => m s -> Stream (StateT s m) a -> Stream m (s, a)
- runReaderT :: Monad m => m s -> Stream (ReaderT s m) a -> Stream m a
- withReaderT :: forall (m :: Type -> Type) r2 r1 a. Monad m => (r2 -> r1) -> Stream (ReaderT r1 m) a -> Stream (ReaderT r2 m) a
- evalStateT :: Monad m => m s -> Stream (StateT s m) a -> Stream m a
- liftInner :: forall (m :: Type -> Type) (t :: (Type -> Type) -> Type -> Type) a. (Monad m, MonadTrans t, Monad (t m)) => Stream m a -> Stream (t m) a
- localReaderT :: forall (m :: Type -> Type) r a. Monad m => (r -> r) -> Stream (ReaderT r m) a -> Stream (ReaderT r m) a
- foldlT :: forall (m :: Type -> Type) s b a. (Monad m, Monad (s m), MonadTrans s) => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
- foldrT :: forall (m :: Type -> Type) t a b. (Monad m, Monad (t m), MonadTrans t) => (a -> t m b -> t m b) -> t m b -> Stream m a -> t m b
- usingReaderT :: Monad m => m r -> (Stream (ReaderT r m) a -> Stream (ReaderT r m) a) -> Stream m a -> Stream m a
- usingStateT :: Monad m => m s -> (Stream (StateT s m) a -> Stream (StateT s m) b) -> Stream m a -> Stream m b
- intercalate :: forall (m :: Type -> Type) b c. Monad m => Unfold m b c -> b -> Stream m b -> Stream m c
- mergeBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
- mergeByM :: Monad m => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
- roundRobin :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- interpose :: forall (m :: Type -> Type) c b. Monad m => c -> Unfold m b c -> Stream m b -> Stream m c
- interposeSuffix :: forall (m :: Type -> Type) c b. Monad m => c -> Unfold m b c -> Stream m b -> Stream m c
- intercalateSuffix :: forall (m :: Type -> Type) b c. Monad m => Unfold m b c -> b -> Stream m b -> Stream m c
- takeEndBySeq :: forall (m :: Type -> Type) a. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Stream m a -> Stream m a
- takeEndBySeq_ :: forall (m :: Type -> Type) a. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Stream m a -> Stream m a
- interleave :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- bfsUnfoldEach :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b
- fairUnfoldEach :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b
- unfoldEachSepBySeq :: forall (m :: Type -> Type) b c. Monad m => b -> Unfold m b c -> Stream m b -> Stream m c
- unfoldEachEndBySeq :: forall (m :: Type -> Type) b c. Monad m => b -> Unfold m b c -> Stream m b -> Stream m c
- fairConcatMap :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b) -> Stream m a -> Stream m b
- fairConcatFor :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> (a -> Stream m b) -> Stream m b
- fairConcatForM :: Monad m => Stream m a -> (a -> m (Stream m b)) -> Stream m b
- parseMany :: forall (m :: Type -> Type) a b. Monad m => Parser a m b -> Stream m a -> Stream m (Either ParseError b)
- splitSepBySeq_ :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Fold m a b -> Stream m a -> Stream m b
- splitEndBySeq :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Fold m a b -> Stream m a -> Stream m b
- splitEndBySeq_ :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Fold m a b -> Stream m a -> Stream m b
- wordsBy :: forall (m :: Type -> Type) a b. Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
- parseManyPos :: forall (m :: Type -> Type) a b. Monad m => Parser a m b -> Stream m a -> Stream m (Either ParseErrorPos b)
- parseIterate :: forall (m :: Type -> Type) b a. Monad m => (b -> Parser a m b) -> b -> Stream m a -> Stream m (Either ParseError b)
- parseIteratePos :: forall (m :: Type -> Type) b a. Monad m => (b -> Parser a m b) -> b -> Stream m a -> Stream m (Either ParseErrorPos b)
- data InterleaveState s1 s2
- = InterleaveFirst s1 s2
- | InterleaveSecond s1 s2
- | InterleaveSecondOnly s2
- | InterleaveFirstOnly s1
- interleaveEndBy' :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- interleaveSepBy' :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- interleaveBeginBy :: forall (m :: Type -> Type) a. Stream m a -> Stream m a -> Stream m a
- interleaveEndBy :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- interleaveSepBy :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- mergeMinBy :: (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
- mergeFstBy :: (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
- unfoldEachFoldBy :: forall (m :: Type -> Type) b c a. Fold m b c -> Unfold m a b -> Stream m a -> Stream m c
- data ConcatUnfoldInterleaveState o i
- = ConcatUnfoldInterleaveOuter o [i]
- | ConcatUnfoldInterleaveInner o [i]
- | ConcatUnfoldInterleaveInnerL [i] [i]
- | ConcatUnfoldInterleaveInnerR [i] [i]
- altBfsUnfoldEach :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b
- unfoldEachSepBy :: forall (m :: Type -> Type) c b. Monad m => c -> Unfold m b c -> Stream m b -> Stream m c
- unfoldEachSepByM :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c
- unfoldEachEndBy :: forall (m :: Type -> Type) c b. Monad m => c -> Unfold m b c -> Stream m b -> Stream m c
- unfoldEachEndByM :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c
- intercalateSepBy :: forall (m :: Type -> Type) b c a. Monad m => Unfold m b c -> Stream m b -> Unfold m a c -> Stream m a -> Stream m c
- intercalateEndBy :: forall (m :: Type -> Type) a c b. Monad m => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c
- fairConcatMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b
- unfoldSched :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b
- fairUnfoldSched :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b
- schedMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b
- schedMap :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b) -> Stream m a -> Stream m b
- fairSchedMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b
- fairSchedMap :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b) -> Stream m a -> Stream m b
- schedForM :: Monad m => Stream m a -> (a -> m (Stream m b)) -> Stream m b
- schedFor :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> (a -> Stream m b) -> Stream m b
- fairSchedForM :: Monad m => Stream m a -> (a -> m (Stream m b)) -> Stream m b
- fairSchedFor :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> (a -> Stream m b) -> Stream m b
- foldSequence :: forall (m :: Type -> Type) a b. Stream m (Fold m a b) -> Stream m a -> Stream m b
- foldIterateM :: Monad m => (b -> m (Fold m a b)) -> m b -> Stream m a -> Stream m b
- parseSequence :: forall (m :: Type -> Type) a b. Stream m (Parser a m b) -> Stream m a -> Stream m b
- parseManyTill :: forall a (m :: Type -> Type) b x. Parser a m b -> Parser a m x -> Stream m a -> Stream m b
- groupsWhile :: forall (m :: Type -> Type) a b. Monad m => (a -> a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
- groupsRollingBy :: forall (m :: Type -> Type) a b. Monad m => (a -> a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
- splitOnSuffixSeq :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Bool -> Array a -> Fold m a b -> Stream m a -> Stream m b
- splitBeginBy_ :: forall a (m :: Type -> Type) b. (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
- splitEndBySeqOneOf :: forall a (m :: Type -> Type) b. [Array a] -> Fold m a b -> Stream m a -> Stream m b
- splitSepBySeqOneOf :: forall a (m :: Type -> Type) b. [Array a] -> Fold m a b -> Stream m a -> Stream m b
- splitInnerBy :: Monad m => (f a -> m (f a, Maybe (f a))) -> (f a -> f a -> m (f a)) -> Stream m (f a) -> Stream m (f a)
- splitInnerBySuffix :: Monad m => (f a -> Bool) -> (f a -> m (f a, Maybe (f a))) -> (f a -> f a -> m (f a)) -> Stream m (f a) -> Stream m (f a)
- dropPrefix :: forall (m :: Type -> Type) a. Stream m a -> Stream m a -> Stream m a
- dropInfix :: forall (m :: Type -> Type) a. Stream m a -> Stream m a -> Stream m a
- dropSuffix :: forall (m :: Type -> Type) a. Stream m a -> Stream m a -> Stream m a
- interposeM :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c
- interposeSuffixM :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c
- gintercalate :: forall (m :: Type -> Type) a c b. Monad m => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c
- gintercalateSuffix :: forall (m :: Type -> Type) a c b. Monad m => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c
- unfoldInterleave :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b
- unfoldRoundRobin :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b
- interleaveMin :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- interleaveFst :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- interleaveFstSuffix :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a
- parseManyD :: forall (m :: Type -> Type) a b. Monad m => Parser a m b -> Stream m a -> Stream m (Either ParseError b)
- parseIterateD :: forall (m :: Type -> Type) b a. Monad m => (b -> Parser a m b) -> b -> Stream m a -> Stream m (Either ParseError b)
- groupsBy :: forall (m :: Type -> Type) a b. Monad m => (a -> a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
- splitOnSeq :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Fold m a b -> Stream m a -> Stream m b
- mapMaybe :: forall (m :: Type -> Type) a b. Monad m => (a -> Maybe b) -> Stream m a -> Stream m b
- sequence :: Monad m => Stream m (m a) -> Stream m a
- with :: forall (m :: Type -> Type) a s b. Monad m => (Stream m a -> Stream m (s, a)) -> (((s, a) -> b) -> Stream m (s, a) -> Stream m (s, a)) -> ((s, a) -> b) -> Stream m a -> Stream m a
- filter :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a
- trace :: Monad m => (a -> m b) -> Stream m a -> Stream m a
- catMaybes :: forall (m :: Type -> Type) a. Monad m => Stream m (Maybe a) -> Stream m a
- scanl :: forall (m :: Type -> Type) a b. Monad m => Scanl m a b -> Stream m a -> Stream m b
- scanl1 :: forall (m :: Type -> Type) a. Monad m => (a -> a -> a) -> Stream m a -> Stream m a
- scanl' :: forall (m :: Type -> Type) b a. Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
- scanr :: forall (m :: Type -> Type) a b. Monad m => Scanr m a b -> Stream m a -> Stream m b
- dropWhile :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a
- drop :: forall (m :: Type -> Type) a. Monad m => Int -> Stream m a -> Stream m a
- reverse :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a
- elemIndices :: forall (m :: Type -> Type) a. (Monad m, Eq a) => a -> Stream m a -> Stream m Int
- findIndices :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m Int
- deleteBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a
- intersperse :: forall (m :: Type -> Type) a. Monad m => a -> Stream m a -> Stream m a
- insertBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
- filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
- scanlx' :: forall (m :: Type -> Type) x a b. Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
- intersperseM :: Monad m => m a -> Stream m a -> Stream m a
- postscanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
- postscan :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b
- scanlMany :: forall (m :: Type -> Type) a b. Monad m => Scanl m a b -> Stream m a -> Stream m b
- dropWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
- scan :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b
- scanMany :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b
- indexed :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m (Int, a)
- splitOn :: forall (m :: Type -> Type) a b. Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
- uniqBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Bool) -> Stream m a -> Stream m a
- catLefts :: forall (m :: Type -> Type) a b. Monad m => Stream m (Either a b) -> Stream m a
- catRights :: forall (m :: Type -> Type) a b. Monad m => Stream m (Either a b) -> Stream m b
- catEithers :: forall (m :: Type -> Type) a. Monad m => Stream m (Either a a) -> Stream m a
- postscanl :: forall (m :: Type -> Type) a b. Monad m => Scanl m a b -> Stream m a -> Stream m b
- scanMaybe :: forall (m :: Type -> Type) a b. Monad m => Fold m a (Maybe b) -> Stream m a -> Stream m b
- postscanlMaybe :: forall (m :: Type -> Type) a b. Monad m => Scanl m a (Maybe b) -> Stream m a -> Stream m b
- tap :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m a
- delay :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m a
- intersperseM_ :: Monad m => m b -> Stream m a -> Stream m a
- mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b
- splitSepBy_ :: forall (m :: Type -> Type) a b. Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
- rollingMap :: forall (m :: Type -> Type) a b. Monad m => (Maybe a -> a -> b) -> Stream m a -> Stream m b
- rollingMapM :: Monad m => (Maybe a -> a -> m b) -> Stream m a -> Stream m b
- uniq :: forall a (m :: Type -> Type). (Eq a, Monad m) => Stream m a -> Stream m a
- repeated :: forall (m :: Type -> Type) a. Stream m a -> Stream m a
- prune :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a
- pipe :: forall (m :: Type -> Type) a b. Monad m => Pipe m a b -> Stream m a -> Stream m b
- intersperseEndByM :: Monad m => m a -> Stream m a -> Stream m a
- tapOffsetEvery :: forall (m :: Type -> Type) a b. Monad m => Int -> Int -> Fold m a b -> Stream m a -> Stream m a
- trace_ :: Monad m => m b -> Stream m a -> Stream m a
- foldrS :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b -> Stream m b) -> Stream m b -> Stream m a -> Stream m b
- foldlS :: forall (m :: Type -> Type) b a. Monad m => (Stream m b -> a -> Stream m b) -> Stream m b -> Stream m a -> Stream m b
- scanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
- scanlMAfter' :: Monad m => (b -> a -> m b) -> m b -> (b -> m b) -> Stream m a -> Stream m b
- scanlM :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
- scanlBy :: forall (m :: Type -> Type) b a. Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
- scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
- scanl1' :: forall (m :: Type -> Type) a. Monad m => (a -> a -> a) -> Stream m a -> Stream m a
- scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
- prescanl' :: forall (m :: Type -> Type) b a. Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
- prescanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
- postscanlBy :: forall (m :: Type -> Type) a b. Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
- postscanlM :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
- postscanl' :: forall (m :: Type -> Type) a b. Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
- postscanlMAfter' :: Monad m => (b -> a -> m b) -> m b -> (b -> m b) -> Stream m a -> Stream m b
- postscanlx' :: forall (m :: Type -> Type) x a b. Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
- postscanlMx' :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
- scanlMx' :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
- sampleFromThen :: forall (m :: Type -> Type) a. Monad m => Int -> Int -> Stream m a -> Stream m a
- initNonEmpty :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a
- tailNonEmpty :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a
- takeWhileLast :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a
- takeWhileAround :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a
- dropLast :: forall (m :: Type -> Type) a. Int -> Stream m a -> Stream m a
- dropWhileLast :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a
- dropWhileAround :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a
- intersperseEveryM :: Int -> m a -> Stream m a -> Stream m a
- intersperseEndByEveryM :: Monad m => Int -> m a -> Stream m a -> Stream m a
- intersperseEndByM_ :: Monad m => m b -> Stream m a -> Stream m a
- intersperseBeginByM_ :: Monad m => m b -> Stream m a -> Stream m a
- delayPre :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m a
- delayPost :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m a
- reverseUnbox :: forall (m :: Type -> Type) a. (MonadIO m, Unbox a) => Stream m a -> Stream m a
- reassembleBy :: forall (m :: Type -> Type) a b. Fold m a b -> (a -> a -> Int) -> Stream m a -> Stream m b
- indexedR :: forall (m :: Type -> Type) a. Monad m => Int -> Stream m a -> Stream m (Int, a)
- timestampWith :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m (AbsTime, a)
- timestamped :: forall (m :: Type -> Type) a. MonadIO m => Stream m a -> Stream m (AbsTime, a)
- timeIndexWith :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m (RelTime64, a)
- timeIndexed :: forall (m :: Type -> Type) a. MonadIO m => Stream m a -> Stream m (RelTime64, a)
- rollingMap2 :: forall (m :: Type -> Type) a b. Monad m => (a -> a -> b) -> Stream m a -> Stream m b
- intersperseMSuffix :: Monad m => m a -> Stream m a -> Stream m a
- intersperseMSuffixWith :: Monad m => Int -> m a -> Stream m a -> Stream m a
- intersperseMSuffix_ :: Monad m => m b -> Stream m a -> Stream m a
- intersperseMPrefix_ :: Monad m => m b -> Stream m a -> Stream m a
- strideFromThen :: forall (m :: Type -> Type) a. Monad m => Int -> Int -> Stream m a -> Stream m a
- unionBy :: forall (m :: Type -> Type) a. MonadIO m => (a -> a -> Bool) -> Stream m a -> Stream m a -> Stream m a
- intersectBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Bool) -> Stream m a -> Stream m a -> Stream m a
- deleteFirstsBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Bool) -> Stream m a -> Stream m a -> Stream m a
- innerJoin :: forall (m :: Type -> Type) a b. Monad m => (a -> b -> Bool) -> Stream m a -> Stream m b -> Stream m (a, b)
- sortedIntersectBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
- sortedDeleteFirstsBy :: forall a (m :: Type -> Type). (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
- sortedUnionBy :: forall a (m :: Type -> Type). (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
- innerSortedJoin :: forall a b (m :: Type -> Type). (a -> b -> Ordering) -> Stream m a -> Stream m b -> Stream m (a, b)
- leftSortedJoin :: forall a b (m :: Type -> Type). (a -> b -> Ordering) -> Stream m a -> Stream m b -> Stream m (a, Maybe b)
- outerSortedJoin :: forall a b (m :: Type -> Type). (a -> b -> Ordering) -> Stream m a -> Stream m b -> Stream m (Maybe a, Maybe b)
- ordNub :: forall (m :: Type -> Type) a. (Monad m, Ord a) => Stream m a -> Stream m a
- leftJoin :: forall (m :: Type -> Type) a b. Monad m => (a -> b -> Bool) -> Stream m a -> Stream m b -> Stream m (a, Maybe b)
- outerJoin :: forall (m :: Type -> Type) a b. MonadIO m => (a -> b -> Bool) -> Stream m a -> Stream m b -> Stream m (Maybe a, Maybe b)
- innerOrdJoin :: forall (m :: Type -> Type) k a b. (Monad m, Ord k) => Stream m (k, a) -> Stream m (k, b) -> Stream m (k, a, b)
- leftOrdJoin :: forall k (m :: Type -> Type) a b. (Ord k, Monad m) => Stream m (k, a) -> Stream m (k, b) -> Stream m (k, a, Maybe b)
- outerOrdJoin :: forall k (m :: Type -> Type) a b. (Ord k, MonadIO m) => Stream m (k, a) -> Stream m (k, b) -> Stream m (k, Maybe a, Maybe b)
Documentation
concat :: forall (m :: Type -> Type) a. Monad m => Stream m (Stream m a) -> Stream m a Source #
Flatten a stream of streams to a single stream.
>>>
concat = Stream.concatMap id
Pre-release
foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b Source #
Right fold, lazy for lazy monads and pure streams, and strict for strict monads.
Please avoid using this routine in strict monads like IO unless you need a
strict right fold. This is provided only for use in lazy monads (e.g.
Identity) or pure streams. Note that with this signature it is not possible
to implement a lazy foldr when the monad m
is strict. In that case it
would be strict in its accumulator and therefore would necessarily consume
all its input.
>>>
foldr f z = Stream.foldrM (\a b -> f a <$> b) (return z)
Note: This is similar to Fold.foldr' (the right fold via left fold), but could be more efficient.
mapM :: Monad m => (a -> m b) -> Stream m a -> Stream m b Source #
>>>
mapM f = Stream.sequence . fmap f
Apply a monadic function to each element of the stream and replace it with the output of the resulting action.
>>>
s = Stream.fromList ["a", "b", "c"]
>>>
Stream.fold Fold.drain $ Stream.mapM putStr s
abc
This is functional equivalent of an imperative loop.
loop :: forall (m :: Type -> Type) b a. Monad m => Stream m b -> Stream m a -> Stream m (a, b) Source #
Loop the supplied stream (first argument) around each element of the input
stream (second argument) generating tuples. This is an argument flipped
version of cross
.
fromList :: forall (m :: Type -> Type) a. Applicative m => [a] -> Stream m a Source #
Construct a stream from a list of pure values.
toList :: Monad m => Stream m a -> m [a] Source #
Definitions:
>>>
toList = Stream.foldr (:) []
>>>
toList = Stream.fold Fold.toList
Convert a stream into a list in the underlying monad. The list can be
consumed lazily in a lazy monad (e.g. Identity
). In a strict monad (e.g.
IO) the whole list is generated and buffered before it can be consumed.
Warning! working on large lists accumulated as buffers in memory could be very inefficient, consider using Streamly.Data.Array instead.
Note that this could a bit more efficient compared to Stream.fold
Fold.toList
, and it can fuse with pure list consumers.
uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a)) Source #
Decompose a stream into its head and tail. If the stream is empty, returns
Nothing
. If the stream is non-empty, returns Just (a, ma)
, where a
is
the head of the stream and ma
its tail.
Properties:
>>>
Nothing <- Stream.uncons Stream.nil
>>>
Just ("a", t) <- Stream.uncons (Stream.cons "a" Stream.nil)
This can be used to consume the stream in an imperative manner one element at a time, as it just breaks down the stream into individual elements and we can loop over them as we deem fit. For example, this can be used to convert a streamly stream into other stream types.
All the folds in this module can be expressed in terms of uncons
, however,
this is generally less efficient than specific folds because it takes apart
the stream one element at a time, therefore, does not take adavantage of
stream fusion.
foldBreak
is a more general way of consuming a stream piecemeal.
>>>
:{
uncons xs = do r <- Stream.foldBreak Fold.one xs return $ case r of (Nothing, _) -> Nothing (Just h, t) -> Just (h, t) :}
takeWhile :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a Source #
End the stream as soon as the predicate fails on an element.
take :: forall (m :: Type -> Type) a. Applicative m => Int -> Stream m a -> Stream m a Source #
Take first n
elements from the stream and discard the rest.
splitAt :: String -> Int -> [a] -> ([a], [a]) Source #
Inlined definition. Without the inline "seriallyparsertake" benchmark degrades and parseMany does not fuse. Even using "inline" at the callsite does not help.
concatMap :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b) -> Stream m a -> Stream m b Source #
Map a stream producing function on each element of the stream and then flatten the results into a single stream.
>>>
concatMap f = Stream.concat . fmap f
>>>
concatMap f = Stream.concatMapM (return . f)
>>>
concatMap f = Stream.unfoldEach (Unfold.lmap f Unfold.fromStream)
See argument flipped version concatFor
for more detailed documentation.
NOTE: We recommend using unfoldEach
or unfoldCross
instead of
concatMap
especially in performance critical code. unfoldEach
is much
faster than concatMap
and matches its expressive power in terms of
generating dependent inner streams, there is one important distinction
though: the nesting structure when using unfoldEach
is fixed statically in
the code. In contrast, concatMap
allows dynamic and arbitrary nesting
through monadic composition. This means that deeply nested or
programmatically determined levels of nesting are easier to express and
compose with concatMap
, though often at the cost of performance and
fusion.
zipWith :: forall (m :: Type -> Type) a b c. Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c Source #
WARNING! O(n^2) time complexity wrt number of streams. Suitable for
statically fusing a small number of streams. Use the O(n) complexity
StreamK.zipWith
otherwise.
Stream a
is evaluated first, followed by stream b
, the resulting
elements a
and b
are then zipped using the supplied zip function and the
result c
is yielded to the consumer.
If stream a
or stream b
ends, the zipped stream ends. If stream b
ends
first, the element a
from previous evaluation of stream a
is discarded.
>>>
s1 = Stream.fromList [1,2,3]
>>>
s2 = Stream.fromList [4,5,6]
>>>
Stream.fold Fold.toList $ Stream.zipWith (+) s1 s2
[5,7,9]
fold :: Monad m => Fold m a b -> Stream m a -> m b Source #
Fold a stream using the supplied left Fold
and reducing the resulting
expression strictly at each step. The behavior is similar to foldl'
. A
Fold
can terminate early without consuming the full stream. See the
documentation of individual Fold
s for termination behavior.
Definitions:
>>>
fold f = fmap fst . Stream.foldBreak f
>>>
fold f = Stream.parse (Parser.fromFold f)
Example:
>>>
Stream.fold Fold.sum (Stream.enumerateFromTo 1 100)
5050
foldrM :: Monad m => (a -> m b -> m b) -> m b -> Stream m a -> m b Source #
Right associative/lazy pull fold. foldrM build final stream
constructs
an output structure using the step function build
. build
is invoked with
the next input element and the remaining (lazy) tail of the output
structure. It builds a lazy output expression using the two. When the "tail
structure" in the output expression is evaluated it calls build
again thus
lazily consuming the input stream
until either the output expression built
by build
is free of the "tail" or the input is exhausted in which case
final
is used as the terminating case for the output structure. For more
details see the description in the previous section.
Example, determine if any element is odd
in a stream:
>>>
s = Stream.fromList (2:4:5:undefined)
>>>
step x xs = if odd x then return True else xs
>>>
Stream.foldrM step (return False) s
True
>>>
import Control.Monad (join)
>>>
foldrM f z = join . Stream.foldr f z
data Stream (m :: Type -> Type) a Source #
A stream consists of a step function that generates the next step given a current state, and the current state.
Instances
zipWithM :: Monad m => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c Source #
Like zipWith
but using a monadic zipping function.
unfold :: forall (m :: Type -> Type) a b. Applicative m => Unfold m a b -> a -> Stream m b Source #
Convert an Unfold
into a stream by supplying it an input seed.
>>>
s = Stream.unfold Unfold.replicateM (3, putStrLn "hello")
>>>
Stream.fold Fold.drain s
hello hello hello
append :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
WARNING! O(n^2) time complexity wrt number of streams. Suitable for
statically fusing a small number of streams. Use the O(n) complexity
StreamK.append
otherwise.
Fuses two streams sequentially, yielding all elements from the first stream, and then all elements from the second stream.
>>>
s1 = Stream.fromList [1,2]
>>>
s2 = Stream.fromList [3,4]
>>>
Stream.fold Fold.toList $ s1 `Stream.append` s2
[1,2,3,4]
fromPure :: forall (m :: Type -> Type) a. Applicative m => a -> Stream m a Source #
Create a singleton stream from a pure value.
>>>
fromPure a = a `Stream.cons` Stream.nil
>>>
fromPure = pure
>>>
fromPure = Stream.fromEffect . pure
toStreamK :: forall (m :: Type -> Type) a. Monad m => Stream m a -> StreamK m a Source #
Convert a direct style step encoded StreamD to a CPS encoded StreamK
foldEither :: Monad m => Fold m a b -> Stream m a -> m (Either (Fold m a b) (b, Stream m a)) Source #
Fold resulting in either breaking the stream or continuation of the fold. Instead of supplying the input stream in one go we can run the fold multiple times, each time supplying the next segment of the input stream. If the fold has not yet finished it returns a fold that can be run again otherwise it returns the fold result and the residual stream.
Internal
nilM :: Applicative m => m b -> Stream m a Source #
A stream that terminates without producing any output, but produces a side effect.
>>>
nilM action = Stream.before action Stream.nil
>>>
Stream.fold Fold.toList (Stream.nilM (print "nil"))
"nil" []
Pre-release
consM :: Applicative m => m a -> Stream m a -> Stream m a infixr 5 Source #
Like cons
but fuses an effect instead of a pure value.
fromStreamK :: forall (m :: Type -> Type) a. Applicative m => StreamK m a -> Stream m a Source #
Convert a CPS encoded StreamK to direct style step encoded StreamD
foldMany :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b Source #
Apply a terminating Fold
repeatedly on a stream and emit the results in
the output stream. If the last fold is empty, it's result is not emitted.
This means if the input stream is empty the result is also an empty stream.
See foldManyPost
for an alternate behavior which always results in a
non-empty stream even if the input stream is empty.
Definition:
>>>
foldMany f = Stream.parseMany (Parser.fromFold f)
Example, empty stream, omits the empty fold value:
>>>
f = Fold.take 2 Fold.toList
>>>
fmany = Stream.fold Fold.toList . Stream.foldMany f
>>>
fmany $ Stream.fromList []
[]
Example, omits the last empty fold value:
>>>
fmany $ Stream.fromList [1..4]
[[1,2],[3,4]]
Example, last fold non-empty:
>>>
fmany $ Stream.fromList [1..5]
[[1,2],[3,4],[5]]
Note that using a closed fold e.g. Fold.take 0
, would result in an
infinite stream on a non-empty input stream.
takeEndBy :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a Source #
takeEndBy_ :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a Source #
>>>
takeEndBy_ f = Stream.takeWhile (not . f)
groupsOf :: forall (m :: Type -> Type) a b. Monad m => Int -> Fold m a b -> Stream m a -> Stream m b Source #
Group the input stream into groups of n
elements each and then fold each
group using the provided fold function.
Definition:
>>>
groupsOf n f = Stream.foldMany (Fold.take n f)
Usage:
>>>
Stream.toList $ Stream.groupsOf 2 Fold.toList (Stream.enumerateFromTo 1 10)
[[1,2],[3,4],[5,6],[7,8],[9,10]]
This can be considered as an n-fold version of take
where we apply
take
repeatedly on the leftover stream until the stream exhausts.
drain :: Monad m => Stream m a -> m () Source #
Definitions:
>>>
drain = Stream.fold Fold.drain
>>>
drain = Stream.foldrM (\_ xs -> xs) (return ())
Run a stream, discarding the results.
fromEffect :: Applicative m => m a -> Stream m a Source #
Create a singleton stream from a monadic action.
>>>
fromEffect m = m `Stream.consM` Stream.nil
>>>
fromEffect = Stream.sequence . Stream.fromPure
>>>
Stream.fold Fold.drain $ Stream.fromEffect (putStrLn "hello")
hello
takeWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a Source #
Same as takeWhile
but with a monadic predicate.
crossWith :: forall (m :: Type -> Type) a b c. Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c Source #
Definition:
>>>
crossWith f m1 m2 = fmap f m1 `Stream.crossApply` m2
Note that the second stream is evaluated multiple times.
Also see "Streamly.Data.Unfold.crossWith" for fast fusible static cross product option.
cross :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> Stream m b -> Stream m (a, b) Source #
Given a Stream m a
and Stream m b
generate a stream with all possible
combinations of the tuple (a, b)
.
Definition:
>>>
cross = Stream.crossWith (,)
The second stream is evaluated multiple times. If that is not desired it can
be cached in an Array
and then generated from the array before
calling this function. Caching may also improve performance if the stream is
expensive to evaluate.
Time: O(m x n)
Pre-release
fairCross :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> Stream m b -> Stream m (a, b) Source #
Like cross
but interleaves the outer and inner loops fairly. See
fairConcatFor
for more details.
unfoldEach :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b Source #
unfoldEach unfold stream
uses unfold
to map the input stream elements
to streams and then flattens the generated streams into a single output
stream.
Like concatMap
but uses an Unfold
for stream generation. Unlike
concatMap
this can fuse the Unfold
code with the inner loop and
therefore provide many times better performance.
>>>
concatMap f = Stream.unfoldEach (Unfold.lmap f Unfold.fromStream)
Here is an example of a two level nested loop much faster than
concatMap
based nesting.
>>>
:{
outerLoop = flip Stream.mapM (Stream.fromList [1,2,3]) $ \x -> do liftIO $ putStrLn (show x) return x innerUnfold = Unfold.carry $ Unfold.lmap (const [4,5,6]) Unfold.fromList innerLoop = flip Unfold.mapM innerUnfold $ \(x, y) -> do when (x == 1) $ liftIO $ putStrLn (show y) pure $ (x, y) :}
>>>
Stream.toList $ Stream.unfoldEach innerLoop outerLoop
1 4 5 6 2 3 [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
concatMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b Source #
Map a stream producing monadic function on each element of the stream
and then flatten the results into a single stream. Since the stream
generation function is monadic, unlike concatMap
, it can produce an
effect at the beginning of each iteration of the inner loop.
See unfoldEach
for a faster alternative.
concatFor :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> (a -> Stream m b) -> Stream m b Source #
Map a stream generating function on each element of a stream and
concatenate the results. This is the same as the bind function of the monad
instance. It is just a flipped concatMap
but more convenient to use for
nested use case, feels like an imperative for
loop. It is in fact
equivalent to concat . for
.
>>>
concatFor = flip Stream.concatMap
A concatenating for
loop:
>>>
:{
Stream.toList $ Stream.concatFor (Stream.fromList [1,2,3]) $ \x -> Stream.fromPure x :} [1,2,3]
Use unfoldEach
instead of concatFor
where possible, unfoldEach is much
faster due to fusion.
Nested concatenating for
loops:
>>>
:{
Stream.toList $ Stream.concatFor (Stream.fromList [1,2,3]) $ \x -> Stream.concatFor (Stream.fromList [4,5,6]) $ \y -> Stream.fromPure (x, y) :} [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
If total iterations are kept the same, each increase in the nesting level increases the cost by roughly 2 times.
For significantly faster multi-level nesting, prefer using the better
fusible, applicative-like crossWith
over concatFor
where possible.
concatFor
is monad-like: it allows expressing dependencies between the
outer and the inner loops of the nesting, it means that the stream generated
by the inner loop is dynamically governed by the outer loop. This expressive
power comes at a significant performance cost.
NOTE: We recommend using unfoldEach
or unfoldCross
instead of
concatFor
especially in performance critical code. unfoldEach
is much
faster than concatFor
and matches its expressive power in terms of
generating dependent inner streams, there is one important distinction
though: the nesting structure when using unfoldEach
is fixed statically in
the code. In contrast, concatFor
allows dynamic and arbitrary nesting
through monadic composition. This means that deeply nested or
programmatically determined levels of nesting are easier to express and
compose with concatFor
, though often at the cost of performance and
fusion.
concatForM :: Monad m => Stream m a -> (a -> m (Stream m b)) -> Stream m b Source #
Like concatFor
but maps an effectful function. It allows conveniently
mixing monadic effects with streams.
>>>
import Control.Monad.IO.Class (liftIO)
>>>
:{
Stream.toList $ Stream.concatForM (Stream.fromList [1,2,3]) $ \x -> do liftIO $ putStrLn (show x) pure $ Stream.fromPure x :} 1 2 3 [1,2,3]
Nested concatentating for
loops:
>>>
:{
Stream.toList $ Stream.concatForM (Stream.fromList [1,2,3]) $ \x -> do liftIO $ putStrLn (show x) pure $ Stream.concatForM (Stream.fromList [4,5,6]) $ \y -> do when (x == 1) $ liftIO $ putStrLn (show y) pure $ Stream.fromPure (x, y) :} 1 4 5 6 2 3 [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
eqBy :: Monad m => (a -> b -> Bool) -> Stream m a -> Stream m b -> m Bool Source #
Compare two streams for equality
cmpBy :: Monad m => (a -> b -> Ordering) -> Stream m a -> Stream m b -> m Ordering Source #
Compare two streams lexicographically.
unfoldMany :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b Source #
Deprecated: Please use unfoldEach instead.
unfoldEach unfold stream
uses unfold
to map the input stream elements
to streams and then flattens the generated streams into a single output
stream.
Like concatMap
but uses an Unfold
for stream generation. Unlike
concatMap
this can fuse the Unfold
code with the inner loop and
therefore provide many times better performance.
>>>
concatMap f = Stream.unfoldEach (Unfold.lmap f Unfold.fromStream)
Here is an example of a two level nested loop much faster than
concatMap
based nesting.
>>>
:{
outerLoop = flip Stream.mapM (Stream.fromList [1,2,3]) $ \x -> do liftIO $ putStrLn (show x) return x innerUnfold = Unfold.carry $ Unfold.lmap (const [4,5,6]) Unfold.fromList innerLoop = flip Unfold.mapM innerUnfold $ \(x, y) -> do when (x == 1) $ liftIO $ putStrLn (show y) pure $ (x, y) :}
>>>
Stream.toList $ Stream.unfoldEach innerLoop outerLoop
1 4 5 6 2 3 [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
newtype Nested (m :: Type -> Type) a Source #
A newtype wrapper for the Stream
type with a cross product style monad
instance.
A Monad
bind behaves like a for
loop:
>>>
:{
Stream.fold Fold.toList $ Stream.unNested $ do x <- Stream.Nested $ Stream.fromList [1,2] -- Perform the following actions for each x in the stream return x :} [1,2]
Nested monad binds behave like nested for
loops:
>>>
:{
Stream.fold Fold.toList $ Stream.unNested $ do x <- Stream.Nested $ Stream.fromList [1,2] y <- Stream.Nested $ Stream.fromList [3,4] -- Perform the following actions for each x, for each y return (x, y) :} [(1,3),(1,4),(2,3),(2,4)]
Instances
MonadTrans Nested Source # | |
Defined in Streamly.Internal.Data.Stream.Type | |
MonadIO m => MonadIO (Nested m) Source # | |
Defined in Streamly.Internal.Data.Stream.Type | |
(Foldable m, Monad m) => Foldable (Nested m) Source # | |
Defined in Streamly.Internal.Data.Stream.Type Methods fold :: Monoid m0 => Nested m m0 -> m0 # foldMap :: Monoid m0 => (a -> m0) -> Nested m a -> m0 # foldMap' :: Monoid m0 => (a -> m0) -> Nested m a -> m0 # foldr :: (a -> b -> b) -> b -> Nested m a -> b # foldr' :: (a -> b -> b) -> b -> Nested m a -> b # foldl :: (b -> a -> b) -> b -> Nested m a -> b # foldl' :: (b -> a -> b) -> b -> Nested m a -> b # foldr1 :: (a -> a -> a) -> Nested m a -> a # foldl1 :: (a -> a -> a) -> Nested m a -> a # elem :: Eq a => a -> Nested m a -> Bool # maximum :: Ord a => Nested m a -> a # minimum :: Ord a => Nested m a -> a # | |
Monad m => Applicative (Nested m) Source # | |
Monad m => Functor (Nested m) Source # | |
Monad m => Monad (Nested m) Source # | |
MonadThrow m => MonadThrow (Nested m) Source # | |
Defined in Streamly.Internal.Data.Stream.Type Methods throwM :: (HasCallStack, Exception e) => e -> Nested m a # | |
a ~ Char => IsString (Nested Identity a) Source # | |
Defined in Streamly.Internal.Data.Stream.Type Methods fromString :: String -> Nested Identity a # | |
IsList (Nested Identity a) Source # | |
Defined in Streamly.Internal.Data.Stream.Type | |
Read a => Read (Nested Identity a) Source # | |
Show a => Show (Nested Identity a) Source # | |
Eq a => Eq (Nested Identity a) Source # | |
Ord a => Ord (Nested Identity a) Source # | |
Defined in Streamly.Internal.Data.Stream.Type Methods compare :: Nested Identity a -> Nested Identity a -> Ordering # (<) :: Nested Identity a -> Nested Identity a -> Bool # (<=) :: Nested Identity a -> Nested Identity a -> Bool # (>) :: Nested Identity a -> Nested Identity a -> Bool # (>=) :: Nested Identity a -> Nested Identity a -> Bool # max :: Nested Identity a -> Nested Identity a -> Nested Identity a # min :: Nested Identity a -> Nested Identity a -> Nested Identity a # | |
type Item (Nested Identity a) Source # | |
foldrS :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b -> Stream m b) -> Stream m b -> Stream m a -> Stream m b Source #
foldAddLazy :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Fold m a b Source #
Append a stream to a fold lazily to build an accumulator incrementally.
Example, to continue folding a list of streams on the same sum fold:
>>>
streams = [Stream.fromList [1..5], Stream.fromList [6..10]]
>>>
f = Prelude.foldl Stream.foldAddLazy Fold.sum streams
>>>
Stream.fold f Stream.nil
55
foldAdd :: Monad m => Fold m a b -> Stream m a -> m (Fold m a b) Source #
>>>
foldAdd = flip Fold.addStream
data AppendState s1 s2 Source #
Constructors
AppendFirst s1 | |
AppendSecond s2 |
crossApply :: forall (f :: Type -> Type) a b. Functor f => Stream f (a -> b) -> Stream f a -> Stream f b Source #
Apply a stream of functions to a stream of values and flatten the results.
Note that the second stream is evaluated multiple times.
>>>
crossApply = Stream.crossWith id
crossApplyFst :: forall (f :: Type -> Type) a b. Functor f => Stream f a -> Stream f b -> Stream f a Source #
crossApplySnd :: forall (f :: Type -> Type) a b. Functor f => Stream f a -> Stream f b -> Stream f b Source #
data FairUnfoldState o i Source #
Constructors
FairUnfoldInit o ([i] -> [i]) | |
FairUnfoldNext o ([i] -> [i]) [i] | |
FairUnfoldDrain ([i] -> [i]) [i] |
fairCrossWithM :: Monad m => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c Source #
Like fairCrossWith
but with monadic function argument.
fairCrossWith :: forall (m :: Type -> Type) a b c. Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c Source #
Like crossWith
but interleaves the outer and inner loops fairly. See
fairConcatFor
for more details.
loopBy :: forall (m :: Type -> Type) x b a. Monad m => Unfold m x b -> x -> Stream m a -> Stream m (a, b) Source #
Loop by unfold. Unfold a value into a stream and nest it with the input
stream. This is much faster than loop
due to stream fusion.
data ConcatMapUState o i Source #
Constructors
ConcatMapUOuter o | |
ConcatMapUInner o i |
unfoldCross :: forall (m :: Type -> Type) a b c. Monad m => Unfold m (a, b) c -> Stream m a -> Stream m b -> Stream m c Source #
Generates a cross product of two streams and then unfolds each tuple.
A two level nested loop much faster than concatMap
based nesting.
>>>
:{
outerLoop = flip Stream.mapM (Stream.fromList [1,2,3]) $ \x -> do liftIO $ putStrLn (show x) return x innerLoop = flip Stream.mapM (Stream.fromList [4,5,6]) $ \y -> do -- liftIO $ putStrLn (show y) return y innerUnfold = flip Unfold.mapM Unfold.identity $ \(x,y) -> do when (x == 1) $ liftIO $ putStrLn (show y) pure $ (x, y) :}
>>>
Stream.toList $ Stream.unfoldCross innerUnfold outerLoop innerLoop
1 4 5 6 2 3 [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
Note: unfoldEach
may generate faster code, so use that when possible.
Also see "Streamly.Data.Unfold.cross" for fast fusible static cross product
option.
unfoldIterate :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a Source #
Same as concatIterate
but more efficient due to stream fusion.
Example, list a directory tree using DFS:
>>>
f = Unfold.either (Dir.eitherReaderPaths id) Unfold.nil
>>>
input = Stream.fromEffect (Left <$> Path.fromString ".")
>>>
ls = Stream.unfoldIterate f input
Pre-release
bfsUnfoldIterate :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a Source #
Like unfoldIterate
but uses breadth first style traversal.
Pre-release
altBfsUnfoldIterate :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a Source #
Like bfsUnfoldIterate
but processes the children in reverse order,
therefore, may be slightly faster.
Pre-release
concatIterateScan :: Monad m => (b -> a -> m b) -> (b -> m (Maybe (b, Stream m a))) -> b -> Stream m a Source #
Generate a stream from an initial state, scan and concat the stream, generate a stream again from the final state of the previous scan and repeat the process.
concatIterate :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a Source #
Traverse the stream in depth first style (DFS). Map each element in the input stream to a stream and flatten, recursively map the resulting elements as well to a stream and flatten until no more streams are generated.
Example, list a directory tree using DFS:
>>>
f = either (Just . Dir.readEitherPaths id) (const Nothing)
>>>
input = Stream.fromEffect (Left <$> Path.fromString ".")
>>>
ls = Stream.concatIterate f input
This is equivalent to using concatIterateWith StreamK.append
.
Pre-release
bfsConcatIterate :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a Source #
Similar to concatIterate
except that it traverses the stream in
breadth first style (BFS). First, all the elements in the input stream are
emitted, and then their traversals are emitted.
Example, list a directory tree using BFS:
>>>
f = either (Just . Dir.readEitherPaths id) (const Nothing)
>>>
input = Stream.fromEffect (Left <$> Path.fromString ".")
>>>
ls = Stream.bfsConcatIterate f input
Pre-release
altBfsConcatIterate :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a Source #
Same as concatIterateBfs
except that the traversal of the last
element on a level is emitted first and then going backwards up to the first
element (reversed ordering). This may be slightly faster than
concatIterateBfs
.
data FoldMany s fs b a Source #
Constructors
FoldManyStart s | |
FoldManyFirst fs s | |
FoldManyLoop s fs | |
FoldManyYield b (FoldMany s fs b a) | |
FoldManyDone |
data FoldManyPost s fs b a Source #
Constructors
FoldManyPostStart s | |
FoldManyPostLoop s fs | |
FoldManyPostYield b (FoldManyPost s fs b a) | |
FoldManyPostDone |
foldManyPost :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b Source #
Like foldMany
but evaluates the fold even if the fold did not receive
any input, therefore, always results in a non-empty output even on an empty
stream (default result of the fold).
Example, empty stream, compare with foldMany
:
>>>
f = Fold.take 2 Fold.toList
>>>
fmany = Stream.fold Fold.toList . Stream.foldManyPost f
>>>
fmany $ Stream.fromList []
[[]]
Example, last empty fold is included, compare with foldMany
:
>>>
fmany $ Stream.fromList [1..4]
[[1,2],[3,4],[]]
Example, last fold non-empty, same as foldMany
:
>>>
fmany $ Stream.fromList [1..5]
[[1,2],[3,4],[5]]
Pre-release
foldManySepBy :: forall (m :: Type -> Type) a b. Fold m a b -> Fold m a b -> Stream m a -> Stream m b Source #
Apply fold f1 infix separated by fold f2.
Unimplemented
refoldIterateM :: Monad m => Refold m b a b -> m b -> Stream m a -> Stream m b Source #
Like foldIterateM
but using the Refold
type instead. This could be
much more efficient due to stream fusion.
Internal
bfsReduceIterate :: Monad m => (a -> a -> m a) -> Stream m a -> m (Maybe a) Source #
Binary BFS style reduce, folds a level entirely using the supplied fold function, collecting the outputs as next level of the tree, then repeats the same process on the next level. The last elements of a previously folded level are folded first.
bfsFoldIterate :: Fold m a (Either a a) -> Stream m a -> m (Maybe a) Source #
N-Ary BFS style iterative fold, if the input stream finished before the fold then it returns Left otherwise Right. If the fold returns Left we terminate.
Unimplemented
indexEndBy :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int) Source #
Like splitEndBy
but generates a stream of (index, len) tuples marking
the places where the predicate matches in the stream.
>>>
Stream.toList $ Stream.indexEndBy (== '/') $ Stream.fromList "/home/harendra"
[(0,1),(1,5),(6,8)]
Pre-release
indexEndBy_ :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int) Source #
Like splitEndBy_
but generates a stream of (index, len) tuples marking
the places where the predicate matches in the stream.
>>>
Stream.toList $ Stream.indexEndBy_ (== '/') $ Stream.fromList "/home/harendra"
[(0,0),(1,4),(6,8)]
Pre-release
sliceOnSuffix :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int) Source #
Deprecated: Please use indexEndBy_ instead.
indexOnSuffix :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int) Source #
Deprecated: Please use indexEndBy_ instead.
Like splitEndBy_
but generates a stream of (index, len) tuples marking
the places where the predicate matches in the stream.
>>>
Stream.toList $ Stream.indexEndBy_ (== '/') $ Stream.fromList "/home/harendra"
[(0,0),(1,4),(6,8)]
Pre-release
type CrossStream = Nested Source #
Deprecated: Use Nested instead.
mkCross :: forall (m :: Type -> Type) a. Stream m a -> Nested m a Source #
Deprecated: Use Nested instead.
reduceIterateBfs :: Monad m => (a -> a -> m a) -> Stream m a -> m (Maybe a) Source #
Deprecated: Please use bfsReduceIterate instead.
Binary BFS style reduce, folds a level entirely using the supplied fold function, collecting the outputs as next level of the tree, then repeats the same process on the next level. The last elements of a previously folded level are folded first.
unfoldIterateDfs :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a Source #
Deprecated: Please use unfoldIterate instead.
Same as concatIterate
but more efficient due to stream fusion.
Example, list a directory tree using DFS:
>>>
f = Unfold.either (Dir.eitherReaderPaths id) Unfold.nil
>>>
input = Stream.fromEffect (Left <$> Path.fromString ".")
>>>
ls = Stream.unfoldIterate f input
Pre-release
unfoldIterateBfs :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a Source #
Deprecated: Please use bfsUnfoldIterate instead.
Like unfoldIterate
but uses breadth first style traversal.
Pre-release
unfoldIterateBfsRev :: forall (m :: Type -> Type) a. Monad m => Unfold m a a -> Stream m a -> Stream m a Source #
Deprecated: Please use altBfsUnfoldIterate instead.
Like bfsUnfoldIterate
but processes the children in reverse order,
therefore, may be slightly faster.
Pre-release
concatIterateDfs :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a Source #
Deprecated: Please use concatIterate instead.
Traverse the stream in depth first style (DFS). Map each element in the input stream to a stream and flatten, recursively map the resulting elements as well to a stream and flatten until no more streams are generated.
Example, list a directory tree using DFS:
>>>
f = either (Just . Dir.readEitherPaths id) (const Nothing)
>>>
input = Stream.fromEffect (Left <$> Path.fromString ".")
>>>
ls = Stream.concatIterate f input
This is equivalent to using concatIterateWith StreamK.append
.
Pre-release
concatIterateBfs :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a Source #
Deprecated: Please use bfsConcatIterate instead.
Similar to concatIterate
except that it traverses the stream in
breadth first style (BFS). First, all the elements in the input stream are
emitted, and then their traversals are emitted.
Example, list a directory tree using BFS:
>>>
f = either (Just . Dir.readEitherPaths id) (const Nothing)
>>>
input = Stream.fromEffect (Left <$> Path.fromString ".")
>>>
ls = Stream.bfsConcatIterate f input
Pre-release
concatIterateBfsRev :: forall (m :: Type -> Type) a. Monad m => (a -> Maybe (Stream m a)) -> Stream m a -> Stream m a Source #
Deprecated: Please use altBfsConcatIterate instead.
Same as concatIterateBfs
except that the traversal of the last
element on a level is emitted first and then going backwards up to the first
element (reversed ordering). This may be slightly faster than
concatIterateBfs
.
repeat :: forall (m :: Type -> Type) a. Monad m => a -> Stream m a Source #
Generate an infinite stream by repeating a pure value.
>>>
repeat = Stream.iterate id
>>>
repeat x = Stream.repeatM (pure x)
unfoldr :: forall (m :: Type -> Type) s a. Monad m => (s -> Maybe (a, s)) -> s -> Stream m a Source #
Build a stream by unfolding a pure step function step
starting from a
seed s
. The step function returns the next element in the stream and the
next seed value. When it is done it returns Nothing
and the stream ends.
For example,
>>>
:{
let f b = if b > 2 then Nothing else Just (b, b + 1) in Stream.toList $ Stream.unfoldr f 0 :} [0,1,2]
iterate :: forall (m :: Type -> Type) a. Monad m => (a -> a) -> a -> Stream m a Source #
Generate an infinite stream with x
as the first element and each
successive element derived by applying the function f
on the previous
element.
>>>
Stream.toList $ Stream.take 5 $ Stream.iterate (+1) 1
[1,2,3,4,5]
replicate :: forall (m :: Type -> Type) a. Monad m => Int -> a -> Stream m a Source #
>>>
replicate n = Stream.take n . Stream.repeat
>>>
replicate n x = Stream.replicateM n (pure x)
Generate a stream of length n
by repeating a value n
times.
replicateM :: Monad m => Int -> m a -> Stream m a Source #
>>>
replicateM n = Stream.sequence . Stream.replicate n
Generate a stream by performing a monadic action n
times.
cons :: forall (m :: Type -> Type) a. Applicative m => a -> Stream m a -> Stream m a infixr 5 Source #
WARNING! O(n^2) time complexity wrt number of elements. Use the O(n)
complexity StreamK.cons
unless you want to
statically fuse just a few elements.
Fuse a pure value at the head of an existing stream::
>>>
s = 1 `Stream.cons` Stream.fromList [2,3]
>>>
Stream.toList s
[1,2,3]
Definition:
>>>
cons x xs = return x `Stream.consM` xs
timeout :: AbsTime -> t m () Source #
Generate a singleton event at or after the specified absolute time. Note that this is different from a threadDelay, a threadDelay starts from the time when the action is evaluated, whereas if we use AbsTime based timeout it will immediately expire if the action is evaluated too late.
Unimplemented
times :: forall (m :: Type -> Type). MonadIO m => Stream m (AbsTime, RelTime64) Source #
times
returns a stream of time value tuples with clock of 10 ms
granularity. The first component of the tuple is an absolute time reference
(epoch) denoting the start of the stream and the second component is a time
relative to the reference.
>>>
f = Fold.drainMapM (\x -> print x >> threadDelay 1000000)
>>>
Stream.fold f $ Stream.take 3 $ Stream.times
(AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...)) (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...)) (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
Note: This API is not safe on 32-bit machines.
Pre-release
nil :: forall (m :: Type -> Type) a. Applicative m => Stream m a Source #
A stream that terminates without producing any output or side effect.
>>>
Stream.toList Stream.nil
[]
repeatM :: Monad m => m a -> Stream m a Source #
>>>
repeatM act = Stream.iterateM (const act) act
>>>
repeatM = Stream.sequence . Stream.repeat
Generate a stream by repeatedly executing a monadic action forever.
>>>
:{
repeatAction = Stream.repeatM (threadDelay 1000000 >> print 1) & Stream.take 10 & Stream.fold Fold.drain :}
iterateM :: Monad m => (a -> m a) -> m a -> Stream m a Source #
Generate an infinite stream with the first element generated by the action
m
and each successive element derived by applying the monadic function f
on the previous element.
>>>
:{
Stream.iterateM (\x -> print x >> return (x + 1)) (return 0) & Stream.take 3 & Stream.toList :} 0 1 [0,1,2]
unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a Source #
Build a stream by unfolding a monadic step function starting from a
seed. The step function returns the next element in the stream and the next
seed value. When it is done it returns Nothing
and the stream ends. For
example,
>>>
:{
let f b = if b > 2 then return Nothing else return (Just (b, b + 1)) in Stream.toList $ Stream.unfoldrM f 0 :} [0,1,2]
class Enum a => Enumerable a where Source #
Types that can be enumerated as a stream. The operations in this type
class are equivalent to those in the Enum
type class, except that these
generate a stream instead of a list. Use the functions in
Streamly.Internal.Data.Stream.Enumeration module to define new instances.
Methods
enumerateFrom :: forall (m :: Type -> Type). Monad m => a -> Stream m a Source #
enumerateFrom from
generates a stream starting with the element
from
, enumerating up to maxBound
when the type is Bounded
or
generating an infinite stream when the type is not Bounded
.
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFrom (0 :: Int)
[0,1,2,3]
For Fractional
types, enumeration is numerically stable. However, no
overflow or underflow checks are performed.
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFrom 1.1
[1.1,2.1,3.1,4.1]
enumerateFromTo :: forall (m :: Type -> Type). Monad m => a -> a -> Stream m a Source #
Generate a finite stream starting with the element from
, enumerating
the type up to the value to
. If to
is smaller than from
then an
empty stream is returned.
>>>
Stream.toList $ Stream.enumerateFromTo 0 4
[0,1,2,3,4]
For Fractional
types, the last element is equal to the specified to
value after rounding to the nearest integral value.
>>>
Stream.toList $ Stream.enumerateFromTo 1.1 4
[1.1,2.1,3.1,4.1]
>>>
Stream.toList $ Stream.enumerateFromTo 1.1 4.6
[1.1,2.1,3.1,4.1,5.1]
enumerateFromThen :: forall (m :: Type -> Type). Monad m => a -> a -> Stream m a Source #
enumerateFromThen from then
generates a stream whose first element
is from
, the second element is then
and the successive elements are
in increments of then - from
. Enumeration can occur downwards or
upwards depending on whether then
comes before or after from
. For
Bounded
types the stream ends when maxBound
is reached, for
unbounded types it keeps enumerating infinitely.
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFromThen 0 2
[0,2,4,6]
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFromThen 0 (-2)
[0,-2,-4,-6]
enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => a -> a -> a -> Stream m a Source #
enumerateFromThenTo from then to
generates a finite stream whose
first element is from
, the second element is then
and the successive
elements are in increments of then - from
up to to
. Enumeration can
occur downwards or upwards depending on whether then
comes before or
after from
.
>>>
Stream.toList $ Stream.enumerateFromThenTo 0 2 6
[0,2,4,6]
>>>
Stream.toList $ Stream.enumerateFromThenTo 0 (-2) (-6)
[0,-2,-4,-6]
Instances
Enumerable Int16 Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Int16 -> Stream m Int16 Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Int16 -> Int16 -> Stream m Int16 Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Int16 -> Int16 -> Stream m Int16 Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Int16 -> Int16 -> Int16 -> Stream m Int16 Source # | |
Enumerable Int32 Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Int32 -> Stream m Int32 Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Int32 -> Int32 -> Stream m Int32 Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Int32 -> Int32 -> Stream m Int32 Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Int32 -> Int32 -> Int32 -> Stream m Int32 Source # | |
Enumerable Int64 Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Int64 -> Stream m Int64 Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Int64 -> Int64 -> Stream m Int64 Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Int64 -> Int64 -> Stream m Int64 Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Int64 -> Int64 -> Int64 -> Stream m Int64 Source # | |
Enumerable Int8 Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Int8 -> Stream m Int8 Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Int8 -> Int8 -> Stream m Int8 Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Int8 -> Int8 -> Stream m Int8 Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Int8 -> Int8 -> Int8 -> Stream m Int8 Source # | |
Enumerable Word16 Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Word16 -> Stream m Word16 Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Word16 -> Word16 -> Stream m Word16 Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Word16 -> Word16 -> Stream m Word16 Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Word16 -> Word16 -> Word16 -> Stream m Word16 Source # | |
Enumerable Word32 Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Word32 -> Stream m Word32 Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Word32 -> Word32 -> Stream m Word32 Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Word32 -> Word32 -> Stream m Word32 Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Word32 -> Word32 -> Word32 -> Stream m Word32 Source # | |
Enumerable Word64 Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Word64 -> Stream m Word64 Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Word64 -> Word64 -> Stream m Word64 Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Word64 -> Word64 -> Stream m Word64 Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Word64 -> Word64 -> Word64 -> Stream m Word64 Source # | |
Enumerable Word8 Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Word8 -> Stream m Word8 Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Word8 -> Word8 -> Stream m Word8 Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Word8 -> Word8 -> Stream m Word8 Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Word8 -> Word8 -> Word8 -> Stream m Word8 Source # | |
Enumerable Ordering Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Ordering -> Stream m Ordering Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Ordering -> Ordering -> Stream m Ordering Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Ordering -> Ordering -> Stream m Ordering Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Ordering -> Ordering -> Ordering -> Stream m Ordering Source # | |
Enumerable Integer Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Integer -> Stream m Integer Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Integer -> Integer -> Stream m Integer Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Integer -> Integer -> Stream m Integer Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Integer -> Integer -> Integer -> Stream m Integer Source # | |
Enumerable Natural Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Natural -> Stream m Natural Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Natural -> Natural -> Stream m Natural Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Natural -> Natural -> Stream m Natural Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Natural -> Natural -> Natural -> Stream m Natural Source # | |
Enumerable () Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => () -> Stream m () Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => () -> () -> Stream m () Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => () -> () -> Stream m () Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => () -> () -> () -> Stream m () Source # | |
Enumerable Bool Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Bool -> Stream m Bool Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Bool -> Bool -> Stream m Bool Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Bool -> Bool -> Stream m Bool Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Bool -> Bool -> Bool -> Stream m Bool Source # | |
Enumerable Char Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Char -> Stream m Char Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Char -> Char -> Stream m Char Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Char -> Char -> Stream m Char Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Char -> Char -> Char -> Stream m Char Source # | |
Enumerable Double Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Double -> Stream m Double Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Double -> Double -> Stream m Double Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Double -> Double -> Stream m Double Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Double -> Double -> Double -> Stream m Double Source # | |
Enumerable Float Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Float -> Stream m Float Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Float -> Float -> Stream m Float Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Float -> Float -> Stream m Float Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Float -> Float -> Float -> Stream m Float Source # | |
Enumerable Int Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Int -> Stream m Int Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Int -> Int -> Stream m Int Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Int -> Int -> Stream m Int Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Int -> Int -> Int -> Stream m Int Source # | |
Enumerable Word Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Word -> Stream m Word Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Word -> Word -> Stream m Word Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Word -> Word -> Stream m Word Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Word -> Word -> Word -> Stream m Word Source # | |
Enumerable a => Enumerable (Identity a) Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Identity a -> Stream m (Identity a) Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Identity a -> Identity a -> Stream m (Identity a) Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Identity a -> Identity a -> Stream m (Identity a) Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Identity a -> Identity a -> Identity a -> Stream m (Identity a) Source # | |
Integral a => Enumerable (Ratio a) Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Ratio a -> Stream m (Ratio a) Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Ratio a -> Ratio a -> Stream m (Ratio a) Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Ratio a -> Ratio a -> Stream m (Ratio a) Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Ratio a -> Ratio a -> Ratio a -> Stream m (Ratio a) Source # | |
HasResolution a => Enumerable (Fixed a) Source # | |
Defined in Streamly.Internal.Data.Stream.Generate Methods enumerateFrom :: forall (m :: Type -> Type). Monad m => Fixed a -> Stream m (Fixed a) Source # enumerateFromTo :: forall (m :: Type -> Type). Monad m => Fixed a -> Fixed a -> Stream m (Fixed a) Source # enumerateFromThen :: forall (m :: Type -> Type). Monad m => Fixed a -> Fixed a -> Stream m (Fixed a) Source # enumerateFromThenTo :: forall (m :: Type -> Type). Monad m => Fixed a -> Fixed a -> Fixed a -> Stream m (Fixed a) Source # |
enumerate :: forall (m :: Type -> Type) a. (Monad m, Bounded a, Enumerable a) => Stream m a Source #
enumerateTo :: forall (m :: Type -> Type) a. (Monad m, Bounded a, Enumerable a) => a -> Stream m a Source #
fromFoldable :: forall (m :: Type -> Type) f a. (Monad m, Foldable f) => f a -> Stream m a Source #
>>>
fromFoldable = Prelude.foldr Stream.cons Stream.nil
Construct a stream from a Foldable
containing pure values:
/WARNING: O(n^2), suitable only for a small number of elements in the stream/
enumerateFromStepNum :: forall (m :: Type -> Type) a. (Monad m, Num a) => a -> a -> Stream m a Source #
For floating point numbers if the increment is less than the precision then it just gets lost. Therefore we cannot always increment it correctly by just repeated addition. 9007199254740992 + 1 + 1 :: Double => 9.007199254740992e15 9007199254740992 + 2 :: Double => 9.007199254740994e15
Instead we accumulate the increment counter and compute the increment every time before adding it to the starting number.
This works for Integrals as well as floating point numbers, but enumerateFromStepIntegral is faster for integrals.
enumerateFromThenNum :: forall (m :: Type -> Type) a. (Monad m, Num a) => a -> a -> Stream m a Source #
enumerateFromBounded :: forall (m :: Type -> Type) a. (Monad m, Enumerable a, Bounded a) => a -> Stream m a Source #
>>>
enumerateFromBounded from = Stream.enumerateFromTo from maxBound
enumerateFrom
for Bounded
Enum
types.
enumerateFromToSmall :: forall (m :: Type -> Type) a. (Monad m, Enum a) => a -> a -> Stream m a Source #
enumerateFromTo
for Enum
types not larger than Int
.
enumerateFromThenToSmall :: forall (m :: Type -> Type) a. (Monad m, Enum a) => a -> a -> a -> Stream m a Source #
enumerateFromThenTo
for Enum
types not larger than Int
.
enumerateFromThenSmallBounded :: forall (m :: Type -> Type) a. (Monad m, Enumerable a, Bounded a) => a -> a -> Stream m a Source #
enumerateFromThen
for Enum
types not larger than Int
.
Note: We convert the Enum
to Int
and enumerate the Int
. If a
type is bounded but does not have a Bounded
instance then we can go on
enumerating it beyond the legal values of the type, resulting in the failure
of toEnum
when converting back to Enum
. Therefore we require a Bounded
instance for this function to be safely used.
enumerateFromIntegral :: forall (m :: Type -> Type) a. (Monad m, Integral a, Bounded a) => a -> Stream m a Source #
enumerateFromThenIntegral :: forall (m :: Type -> Type) a. (Monad m, Integral a, Bounded a) => a -> a -> Stream m a Source #
Enumerate an Integral
type in steps. enumerateFromThenIntegral from
then
generates a stream whose first element is from
, the second element
is then
and the successive elements are in increments of then - from
.
The stream is bounded by the size of the Integral
type.
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFromThenIntegral (0 :: Int) 2
[0,2,4,6]
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFromThenIntegral (0 :: Int) (-2)
[0,-2,-4,-6]
enumerateFromToIntegral :: forall (m :: Type -> Type) a. (Monad m, Integral a) => a -> a -> Stream m a Source #
Enumerate an Integral
type up to a given limit.
enumerateFromToIntegral from to
generates a finite stream whose first
element is from
and successive elements are in increments of 1
up to
to
.
>>>
Stream.toList $ Stream.enumerateFromToIntegral 0 4
[0,1,2,3,4]
enumerateFromThenToIntegral :: forall (m :: Type -> Type) a. (Monad m, Integral a) => a -> a -> a -> Stream m a Source #
Enumerate an Integral
type in steps up to a given limit.
enumerateFromThenToIntegral from then to
generates a finite stream whose
first element is from
, the second element is then
and the successive
elements are in increments of then - from
up to to
.
>>>
Stream.toList $ Stream.enumerateFromThenToIntegral 0 2 6
[0,2,4,6]
>>>
Stream.toList $ Stream.enumerateFromThenToIntegral 0 (-2) (-6)
[0,-2,-4,-6]
enumerateFromStepIntegral :: forall a (m :: Type -> Type). (Integral a, Monad m) => a -> a -> Stream m a Source #
enumerateFromStepIntegral from step
generates an infinite stream whose
first element is from
and the successive elements are in increments of
step
.
CAUTION: This function is not safe for finite integral types. It does not check for overflow, underflow or bounds.
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFromStepIntegral 0 2
[0,2,4,6]
>>>
Stream.toList $ Stream.take 3 $ Stream.enumerateFromStepIntegral 0 (-2)
[0,-2,-4]
enumerateFromFractional :: forall (m :: Type -> Type) a. (Monad m, Fractional a) => a -> Stream m a Source #
Numerically stable enumeration from a Fractional
number in steps of size
1
. enumerateFromFractional from
generates a stream whose first element
is from
and the successive elements are in increments of 1
. No overflow
or underflow checks are performed.
This is the equivalent to enumFrom
for Fractional
types. For example:
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFromFractional 1.1
[1.1,2.1,3.1,4.1]
enumerateFromToFractional :: forall (m :: Type -> Type) a. (Monad m, Fractional a, Ord a) => a -> a -> Stream m a Source #
Numerically stable enumeration from a Fractional
number to a given
limit. enumerateFromToFractional from to
generates a finite stream whose
first element is from
and successive elements are in increments of 1
up
to to
.
This is the equivalent of enumFromTo
for Fractional
types. For
example:
>>>
Stream.toList $ Stream.enumerateFromToFractional 1.1 4
[1.1,2.1,3.1,4.1]
>>>
Stream.toList $ Stream.enumerateFromToFractional 1.1 4.6
[1.1,2.1,3.1,4.1,5.1]
Notice that the last element is equal to the specified to
value after
rounding to the nearest integer.
enumerateFromThenFractional :: forall (m :: Type -> Type) a. (Monad m, Fractional a) => a -> a -> Stream m a Source #
Numerically stable enumeration from a Fractional
number in steps.
enumerateFromThenFractional from then
generates a stream whose first
element is from
, the second element is then
and the successive elements
are in increments of then - from
. No overflow or underflow checks are
performed.
This is the equivalent of enumFromThen
for Fractional
types. For
example:
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFromThenFractional 1.1 2.1
[1.1,2.1,3.1,4.1]
>>>
Stream.toList $ Stream.take 4 $ Stream.enumerateFromThenFractional 1.1 (-2.1)
[1.1,-2.1,-5.300000000000001,-8.500000000000002]
enumerateFromThenToFractional :: forall (m :: Type -> Type) a. (Monad m, Fractional a, Ord a) => a -> a -> a -> Stream m a Source #
Numerically stable enumeration from a Fractional
number in steps up to a
given limit. enumerateFromThenToFractional from then to
generates a
finite stream whose first element is from
, the second element is then
and the successive elements are in increments of then - from
up to to
.
This is the equivalent of enumFromThenTo
for Fractional
types. For
example:
>>>
Stream.toList $ Stream.enumerateFromThenToFractional 0.1 2 6
[0.1,2.0,3.9,5.799999999999999]
>>>
Stream.toList $ Stream.enumerateFromThenToFractional 0.1 (-2) (-6)
[0.1,-2.0,-4.1000000000000005,-6.200000000000001]
timesWith :: forall (m :: Type -> Type). MonadIO m => Double -> Stream m (AbsTime, RelTime64) Source #
timesWith g
returns a stream of time value tuples. The first component
of the tuple is an absolute time reference (epoch) denoting the start of the
stream and the second component is a time relative to the reference.
The argument g
specifies the granularity of the relative time in seconds.
A lower granularity clock gives higher precision but is more expensive in
terms of CPU usage. Any granularity lower than 1 ms is treated as 1 ms.
>>>
import Control.Concurrent (threadDelay)
>>>
f = Fold.drainMapM (\x -> print x >> threadDelay 1000000)
>>>
Stream.fold f $ Stream.take 3 $ Stream.timesWith 0.01
(AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...)) (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...)) (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
Note: This API is not safe on 32-bit machines.
Pre-release
absTimes :: forall (m :: Type -> Type). MonadIO m => Stream m AbsTime Source #
absTimes
returns a stream of absolute timestamps using a clock of 10 ms
granularity.
>>>
f = Fold.drainMapM print
>>>
Stream.fold f $ Stream.delayPre 1 $ Stream.take 3 $ Stream.absTimes
AbsTime (TimeSpec {sec = ..., nsec = ...}) AbsTime (TimeSpec {sec = ..., nsec = ...}) AbsTime (TimeSpec {sec = ..., nsec = ...})
Note: This API is not safe on 32-bit machines.
Pre-release
absTimesWith :: forall (m :: Type -> Type). MonadIO m => Double -> Stream m AbsTime Source #
absTimesWith g
returns a stream of absolute timestamps using a clock of
granularity g
specified in seconds. A low granularity clock is more
expensive in terms of CPU usage. Any granularity lower than 1 ms is treated
as 1 ms.
>>>
f = Fold.drainMapM print
>>>
Stream.fold f $ Stream.delayPre 1 $ Stream.take 3 $ Stream.absTimesWith 0.01
AbsTime (TimeSpec {sec = ..., nsec = ...}) AbsTime (TimeSpec {sec = ..., nsec = ...}) AbsTime (TimeSpec {sec = ..., nsec = ...})
Note: This API is not safe on 32-bit machines.
Pre-release
relTimes :: forall (m :: Type -> Type). MonadIO m => Stream m RelTime64 Source #
relTimes
returns a stream of relative time values starting from 0,
using a clock of granularity 10 ms.
>>>
f = Fold.drainMapM print
>>>
Stream.fold f $ Stream.delayPre 1 $ Stream.take 3 $ Stream.relTimes
RelTime64 (NanoSecond64 ...) RelTime64 (NanoSecond64 ...) RelTime64 (NanoSecond64 ...)
Note: This API is not safe on 32-bit machines.
Pre-release
relTimesWith :: forall (m :: Type -> Type). MonadIO m => Double -> Stream m RelTime64 Source #
relTimesWith g
returns a stream of relative time values starting from 0,
using a clock of granularity g
specified in seconds. A low granularity
clock is more expensive in terms of CPU usage. Any granularity lower than 1
ms is treated as 1 ms.
>>>
f = Fold.drainMapM print
>>>
Stream.fold f $ Stream.delayPre 1 $ Stream.take 3 $ Stream.relTimesWith 0.01
RelTime64 (NanoSecond64 ...) RelTime64 (NanoSecond64 ...) RelTime64 (NanoSecond64 ...)
Note: This API is not safe on 32-bit machines.
Pre-release
durations :: Double -> t m RelTime64 Source #
durations g
returns a stream of relative time values measuring the time
elapsed since the immediate predecessor element of the stream was generated.
The first element of the stream is always 0. durations
uses a clock of
granularity g
specified in seconds. A low granularity clock is more
expensive in terms of CPU usage. The minimum granularity is 1 millisecond.
Durations lower than 1 ms will be 0.
Note: This API is not safe on 32-bit machines.
Unimplemented
fromFoldableM :: (Monad m, Foldable f) => f (m a) -> Stream m a Source #
>>>
fromFoldableM = Prelude.foldr Stream.consM Stream.nil
Construct a stream from a Foldable
containing pure values:
/WARNING: O(n^2), suitable only for a small number of elements in the stream/
fromPtrN :: forall (m :: Type -> Type) a. (Monad m, Storable a) => Int -> Ptr a -> Stream m a Source #
fromCString# :: forall (m :: Type -> Type). Monad m => Addr# -> Stream m Word8 Source #
Read bytes from an immutable Addr#
until a 0 byte is encountered, the 0
byte is not included in the stream.
>>>
:set -XMagicHash
>>>
fromCString# addr = Stream.takeWhile (/= 0) $ Stream.fromPtr $ (Ptr addr :: Ptr Word8)
Unsafe: The caller is responsible for safe addressing.
Note that this is completely safe when reading from Haskell string literals because they are guaranteed to be NULL terminated:
>>>
Stream.toList $ Stream.fromCString# "\1\2\3\0"#
[1,2,3]
fromW16CString# :: forall (m :: Type -> Type). Monad m => Addr# -> Stream m Word16 Source #
Read Word16 from an immutable Addr#
until a 0 Word16 is encountered, the
0 Word16 is not included in the stream.
>>>
:set -XMagicHash
>>>
fromW16CString# addr = Stream.takeWhile (/= 0) $ Stream.fromPtr $ (Ptr addr :: Ptr Word16)
Unsafe: The caller is responsible for safe addressing.
fromByteStr# :: forall (m :: Type -> Type). Monad m => Addr# -> Stream m Word8 Source #
Deprecated: Please use fromCString# instead
mapM_ :: Monad m => (a -> m b) -> Stream m a -> m () Source #
Execute a monadic action for each element of the Stream
uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a)) Source #
Decompose a stream into its head and tail. If the stream is empty, returns
Nothing
. If the stream is non-empty, returns Just (a, ma)
, where a
is
the head of the stream and ma
its tail.
Properties:
>>>
Nothing <- Stream.uncons Stream.nil
>>>
Just ("a", t) <- Stream.uncons (Stream.cons "a" Stream.nil)
This can be used to consume the stream in an imperative manner one element at a time, as it just breaks down the stream into individual elements and we can loop over them as we deem fit. For example, this can be used to convert a streamly stream into other stream types.
All the folds in this module can be expressed in terms of uncons
, however,
this is generally less efficient than specific folds because it takes apart
the stream one element at a time, therefore, does not take adavantage of
stream fusion.
foldBreak
is a more general way of consuming a stream piecemeal.
>>>
:{
uncons xs = do r <- Stream.foldBreak Fold.one xs return $ case r of (Nothing, _) -> Nothing (Just h, t) -> Just (h, t) :}
tail :: Monad m => Stream m a -> m (Maybe (Stream m a)) Source #
Same as:
>>>
tail = fmap (fmap snd) . Stream.uncons
Does not fuse, has the same performance as the StreamK version.
stripPrefix :: (Monad m, Eq a) => Stream m a -> Stream m a -> m (Maybe (Stream m a)) Source #
stripPrefix prefix input
strips the prefix
stream from the input
stream if it is a prefix of input. Returns Nothing
if the input does not
start with the given prefix, stripped input otherwise. Returns Just nil
when the prefix is the same as the input stream.
Space: O(1)
isPrefixOf :: (Monad m, Eq a) => Stream m a -> Stream m a -> m Bool Source #
Returns True
if the first stream is the same as or a prefix of the
second. A stream is a prefix of itself.
>>>
Stream.isPrefixOf (Stream.fromList "hello") (Stream.fromList "hello" :: Stream IO Char)
True
isSuffixOf :: (Monad m, Eq a) => Stream m a -> Stream m a -> m Bool Source #
Returns True
if the first stream is a suffix of the second. A stream is
considered a suffix of itself.
>>>
Stream.isSuffixOf (Stream.fromList "hello") (Stream.fromList "hello" :: Stream IO Char)
True
Space: O(n)
, buffers entire input stream and the suffix.
Pre-release
Suboptimal - Help wanted.
isInfixOf :: (MonadIO m, Eq a, Enum a, Unbox a) => Stream m a -> Stream m a -> m Bool Source #
Returns True
if the first stream is an infix of the second. A stream is
considered an infix of itself.
>>>
s = Stream.fromList "hello" :: Stream IO Char
>>>
Stream.isInfixOf s s
True
Space: O(n)
worst case where n
is the length of the infix.
Pre-release
Requires Storable
constraint
isSubsequenceOf :: (Monad m, Eq a) => Stream m a -> Stream m a -> m Bool Source #
Returns True
if all the elements of the first stream occur, in order, in
the second stream. The elements do not have to occur consecutively. A stream
is a subsequence of itself.
>>>
Stream.isSubsequenceOf (Stream.fromList "hlo") (Stream.fromList "hello" :: Stream IO Char)
True
stripSuffix :: (Monad m, Eq a) => Stream m a -> Stream m a -> m (Maybe (Stream m a)) Source #
Drops the given suffix from a stream. Returns Nothing
if the stream does
not end with the given suffix. Returns Just nil
when the suffix is the
same as the stream.
It may be more efficient to convert the stream to an Array and use stripSuffix on that especially if the elements have a Storable or Prim instance.
Space: O(n)
, buffers the entire input stream as well as the suffix
Pre-release
parseD :: Monad m => Parser a m b -> Stream m a -> m (Either ParseError b) Source #
Deprecated: Please use parse instead.
Parse a stream using the supplied Parser
.
Parsers (See Streamly.Internal.Data.Parser) are more powerful folds that add backtracking and error functionality to terminating folds. Unlike folds, parsers may not always result in a valid output, they may result in an error. For example:
>>>
Stream.parse (Parser.takeEQ 1 Fold.drain) Stream.nil
Left (ParseError "takeEQ: Expecting exactly 1 elements, input terminated on 0")
Note: parse p
is not the same as head . parseMany p
on an empty stream.
parseBreak :: Monad m => Parser a m b -> Stream m a -> m (Either ParseError b, Stream m a) Source #
Parse a stream using the supplied Parser
.
parseBreakPos :: Monad m => Parser a m b -> Stream m a -> m (Either ParseErrorPos b, Stream m a) Source #
Like parseBreak
but includes stream position information in the error
messages.
parse :: Monad m => Parser a m b -> Stream m a -> m (Either ParseError b) Source #
Parse a stream using the supplied Parser
.
Parsers (See Streamly.Internal.Data.Parser) are more powerful folds that add backtracking and error functionality to terminating folds. Unlike folds, parsers may not always result in a valid output, they may result in an error. For example:
>>>
Stream.parse (Parser.takeEQ 1 Fold.drain) Stream.nil
Left (ParseError "takeEQ: Expecting exactly 1 elements, input terminated on 0")
Note: parse p
is not the same as head . parseMany p
on an empty stream.
parsePos :: Monad m => Parser a m b -> Stream m a -> m (Either ParseErrorPos b) Source #
Like parse
but includes stream position information in the error
messages.
>>>
Stream.parsePos (Parser.takeEQ 2 Fold.drain) (Stream.fromList [1])
Left (ParseErrorPos 1 "takeEQ: Expecting exactly 2 elements, input terminated on 1")
isSuffixOfUnbox :: (MonadIO m, Eq a, Unbox a) => Stream m a -> Stream m a -> m Bool Source #
Much faster than isSuffixOf
.
stripSuffixUnbox :: (MonadIO m, Eq a, Unbox a) => Stream m a -> Stream m a -> m (Maybe (Stream m a)) Source #
Much faster than stripSuffix
.
parseBreakD :: Monad m => Parser a m b -> Stream m a -> m (Either ParseError b, Stream m a) Source #
Deprecated: Please use parseBreak instead.
Parse a stream using the supplied Parser
.
onException :: MonadCatch m => m b -> Stream m a -> Stream m a Source #
Run the action m b
if the stream evaluation is aborted due to an
exception. The exception is not caught, simply rethrown.
Observes exceptions only in the stream generation, and not in stream consumers.
Inhibits stream fusion
handle :: (MonadCatch m, Exception e) => (e -> m (Stream m a)) -> Stream m a -> Stream m a Source #
When evaluating a stream if an exception occurs, stream evaluation aborts and the specified exception handler is run with the exception as argument. The exception is caught and handled unless the handler decides to rethrow it. Note that exception handling is not applied to the stream returned by the exception handler.
Observes exceptions only in the stream generation, and not in stream consumers.
Inhibits stream fusion
withAcquireIO :: forall (m :: Type -> Type) a. (MonadIO m, MonadCatch m) => (AcquireIO -> Stream m a) -> Stream m a Source #
Like bracketIO
but with on-demand allocations and manual release
facility.
Here is an example:
>>>
:{
close x h = do putStrLn $ "closing: " ++ x hClose h :}
>>>
:{
generate ref = Stream.fromList ["file1", "file2"] & Stream.mapM (\x -> do (h, release) <- Exception.acquire ref (openFile x ReadMode) (close x) -- use h here threadDelay 1000000 when (x == "file1") $ do putStrLn $ "Manually releasing: " ++ x release return x ) & Stream.trace print :}
>>>
:{
run = Stream.withAcquireIO generate & Stream.fold Fold.drain :}
In the above code, you should see the "closing:" message for both the files, and only once for each file. Make sure you create "file1" and "file2" before running it.
Here is an example for just registering hooks to be called eventually:
>>>
:{
generate ref = Stream.fromList ["file1", "file2"] & Stream.mapM (\x -> do Exception.register ref $ putStrLn $ "saw: " ++ x threadDelay 1000000 return x ) & Stream.trace print :}
>>>
:{
run = Stream.withAcquireIO generate & Stream.fold Fold.drain :}
In the above code, even if you interrupt the program with CTRL-C you should still see the "saw:" message for the elements seen before the interrupt.
See bracketIO
documentation for the caveats related to partially consumed
streams and async exceptions.
Use monad level bracket Streamly.Control.Exception.'Streamly..Control.Exception.withAcquireIO' for guaranteed cleanup in the entire pipeline, however, monad level bracket does not provide an automatic cleanup at the end of the stream; you can only release resources manually or via automatic cleanup at the end of the monad bracket. The end of stream cleanup is useful especially in nested streams where we want to cleanup at the end of every inner stream instead of waiting for the outer stream to end for cleaning up to happen.
bracketIO :: forall (m :: Type -> Type) b c a. (MonadIO m, MonadCatch m) => IO b -> (b -> IO c) -> (b -> Stream m a) -> Stream m a Source #
The alloc action IO b
is executed with async exceptions disabled but keeping
blocking operations interruptible (see mask
). Uses the
output b
of the IO action as input to the function b -> Stream m a
to
generate an output stream.
b
is usually a resource allocated under the IO monad, e.g. a file handle, that
requires a cleanup after use. The cleanup is done using the b -> IO c
action. bracketIO guarantees that the allocated resource is eventually (see
details below) cleaned up even in the face of sync or async exceptions. If
an exception occurs it is not caught, simply rethrown.
bracketIO
only guarantees that the cleanup action runs, and it runs with
async exceptions enabled. The action must ensure that it can successfully
cleanup the resource in the face of sync or async exceptions.
Best case: Cleanup happens immediately in the following cases:
- the stream is consumed completely
- an exception occurs in the bracketed part of the pipeline
Worst case: In the following cases cleanup is deferred to GC.
- the bracketed stream is partially consumed and abandoned
- pipeline is aborted due to an exception outside the bracket
Use Streamly.Control.Exception.withAcquireIO
for covering the entire pipeline with guaranteed cleanup at the end of
bracket.
Observes exceptions only in the stream generation, and not in stream consumers.
See also: bracketUnsafe
Inhibits stream fusion
Arguments
:: Monad m | |
=> m c | before |
-> (c -> m d) | after, on normal stop |
-> (c -> e -> Stream m b -> m (Stream m b)) | on exception |
-> (forall s. m s -> m (Either e s)) | try (exception handling) |
-> (c -> Stream m b) | stream generator |
-> Stream m b |
Like gbracket
but with following differences:
- alloc action
m c
runs with async exceptions enabled - cleanup action
c -> m d
won't run if the stream is garbage collected after partial evaluation.
Inhibits stream fusion
Pre-release
before :: Monad m => m b -> Stream m a -> Stream m a Source #
Run the action m b
before the stream yields its first element.
Same as the following but more efficient due to fusion:
>>>
before action xs = Stream.concatMap (const xs) (Stream.fromEffect action)
afterIO :: forall (m :: Type -> Type) b a. MonadIO m => IO b -> Stream m a -> Stream m a Source #
Run the action IO b
whenever the stream is evaluated to completion, or
if it is garbage collected after a partial lazy evaluation.
The semantics of the action IO b
are similar to the semantics of cleanup
action in bracketIO
.
See also afterUnsafe
finallyIO :: forall (m :: Type -> Type) b a. (MonadIO m, MonadCatch m) => IO b -> Stream m a -> Stream m a Source #
Run the action IO b
whenever the stream stream stops normally, aborts
due to an exception or if it is garbage collected after a partial lazy
evaluation.
The semantics of running the action IO b
are similar to the cleanup action
semantics described in bracketIO
.
>>>
finallyIO release stream = Stream.bracketIO (return ()) (const release) (const stream)
See also finallyIO' for stricter resource release guarantees.
See also finallyUnsafe
Inhibits stream fusion
finallyIO' :: forall (m :: Type -> Type) b a. MonadIO m => AcquireIO -> IO b -> Stream m a -> Stream m a Source #
Like finallyIO, based on bracketIO' semantics.
finallyIO'' :: forall (m :: Type -> Type) b a. (MonadIO m, MonadCatch m) => AcquireIO -> IO b -> Stream m a -> Stream m a Source #
Like finallyIO, based on bracketIO'' semantics.
bracketIO' :: forall (m :: Type -> Type) b c a. MonadIO m => AcquireIO -> IO b -> (b -> IO c) -> (b -> Stream m a) -> Stream m a Source #
Like bracketIO
but requires an AcquireIO
reference in the underlying monad
of the stream, and guarantees that all resources are freed before the
scope of the monad level resource manager
(Streamly.Control.Exception.withAcquireIO
)
ends. Where fusion matters, this combinator can be much faster than bracketIO
as it
allows stream fusion.
Best case: Cleanup happens immediately if the stream is consumed completely.
Worst case: In the following cases cleanup is guaranteed to occur at the end of the monad level bracket. However, if a GC occurs then cleanup will occur even earlier than that.
- the bracketed stream is partially consumed and abandoned
- pipeline is aborted due to an exception
This is the recommended default bracket operation.
Note: You can use acquire
directly, instead of using this combinator, if
you don’t need to release the resource when the stream ends. However, if
you're using the stream inside another stream (like with concatMap), you
usually do want to release it at the end of the stream.
Allows stream fusion
bracketIO'' :: forall (m :: Type -> Type) b c a. (MonadIO m, MonadCatch m) => AcquireIO -> IO b -> (b -> IO c) -> (b -> Stream m a) -> Stream m a Source #
Like bracketIO, the only difference is that there is a guarantee that the
resources will be freed at the end of the monad level bracket
(AcquireIO
).
Best case: Cleanup happens immediately in the following cases:
- the stream is consumed completely
- an exception occurs in the bracketed part of the pipeline
Worst case: In the following cases cleanup is guaranteed to occur at the end of the monad level bracket. However, if a GC occurs before that then cleanup will occur early.
- the bracketed stream is partially consumed and abandoned
- pipeline is aborted due to an exception outside the bracket
Note: Instead of using this combinator you can directly use
acquire
if you do not care about releasing the resource at the end of the stream
and if you are not recovering from an exception using handle
. You may want
to care about releasing the resource at the end of a stream if you are using
it in a nested manner (e.g. in concatMap).
Inhibits stream fusion
bracketIO3 :: forall (m :: Type -> Type) b c d e a. (MonadIO m, MonadCatch m) => IO b -> (b -> IO c) -> (b -> IO d) -> (b -> IO e) -> (b -> Stream m a) -> Stream m a Source #
Like bracketIO
but can use 3 separate cleanup actions depending on the
mode of termination:
- When the stream stops normally
- When the stream is garbage collected
- When the stream encounters an exception
bracketIO3 before onStop onGC onException action
runs action
using the
result of before
. If the stream stops, onStop
action is executed, if the
stream is abandoned onGC
is executed, if the stream encounters an
exception onException
is executed.
The exception is not caught, it is rethrown.
Inhibits stream fusion
Pre-release
afterUnsafe :: Monad m => m b -> Stream m a -> Stream m a Source #
Like after
, with following differences:
- action
m b
won't run if the stream is garbage collected after partial evaluation. - Monad
m
does not require any other constraints. - has slightly better performance than
after
.
Same as the following, but with stream fusion:
>>>
afterUnsafe action xs = xs <> Stream.nilM action
Pre-release
finallyUnsafe :: MonadCatch m => m b -> Stream m a -> Stream m a Source #
Like finally
with following differences:
- action
m b
won't run if the stream is garbage collected after partial evaluation. - has slightly better performance than
finallyIO
.
Inhibits stream fusion
Pre-release
Arguments
:: MonadIO m | |
=> IO c | before |
-> (c -> IO d1) | on normal stop |
-> (c -> e -> Stream m b -> IO (Stream m b)) | on exception |
-> (c -> IO d2) | on GC without normal stop or exception |
-> (forall s. m s -> m (Either e s)) | try (exception handling) |
-> (c -> Stream m b) | stream generator |
-> Stream m b |
Run the alloc action m c
with async exceptions disabled but keeping
blocking operations interruptible (see mask
). Use the
output c
as input to c -> Stream m b
to generate an output stream. When
generating the stream use the supplied try
operation forall s. m s -> m
(Either e s)
to catch synchronous exceptions. If an exception occurs run
the exception handler c -> e -> Stream m b -> m (Stream m b)
. Note that
gbracket
does not rethrow the exception, it has to be done by the
exception handler if desired.
The cleanup action c -> m d
, runs whenever the stream ends normally, due
to a sync or async exception or if it gets garbage collected after a partial
lazy evaluation. See bracket
for the semantics of the cleanup action.
gbracket
can express all other exception handling combinators.
Inhibits stream fusion
Pre-release
bracketUnsafe :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a Source #
Like bracket
but with following differences:
- alloc action
m b
runs with async exceptions enabled - cleanup action
b -> m c
won't run if the stream is garbage collected after partial evaluation. - has slightly better performance than
bracketIO
.
Inhibits stream fusion
Pre-release
withAcquireIO' :: forall (m :: Type -> Type) a. AcquireIO -> (AcquireIO -> Stream m a) -> Stream m a Source #
We can also combine the stream local withAcquireIO
with the global monad
level bracket
Streamly.Internal.Control.Exception.withAcquireIO
.
The release actions returned by the local allocator can be registered to be
called by the monad level bracket. This way we can guarantee that in the
worst case release actions happen at the end of bracket and do not depend on
GC. This is the most powerful way of allocating resources on-demand with
manual release inside a stream. If required a custom combinator can be
written to register the local allocator's release in the global allocator
automatically.
Unimplemented
ghandle :: (MonadCatch m, Exception e) => (e -> Stream m a -> m (Stream m a)) -> Stream m a -> Stream m a Source #
Like handle
but the exception handler is also provided with the stream
that generated the exception as input. The exception handler can thus
re-evaluate the stream to retry the action that failed. The exception
handler can again call ghandle
on it to retry the action multiple times.
This is highly experimental. In a stream of actions we can map the stream with a retry combinator to retry each action on failure.
Inhibits stream fusion
Pre-release
morphInner :: Monad n => (forall x. m x -> n x) -> Stream m a -> Stream n a Source #
Transform the inner monad of a stream using a natural transformation.
Example, generalize the inner monad from Identity to any other:
>>>
generalizeInner = Stream.morphInner (return . runIdentity)
Also known as hoist.
generalizeInner :: forall (m :: Type -> Type) a. Monad m => Stream Identity a -> Stream m a Source #
Generalize the inner monad of the stream from Identity
to any monad.
Definition:
>>>
generalizeInner = Stream.morphInner (return . runIdentity)
liftInnerWith :: Monad (t m) => (forall b. m b -> t m b) -> Stream m a -> Stream (t m) a Source #
Lift the inner monad m
of a stream Stream m a
to t m
using the
supplied lift function.
runInnerWith :: Monad m => (forall b. t m b -> m b) -> Stream (t m) a -> Stream m a Source #
Evaluate the inner monad of a stream using the supplied runner function.
runInnerWithState :: Monad m => (forall b. s -> t m b -> m (b, s)) -> m s -> Stream (t m) a -> Stream m (s, a) Source #
Evaluate the inner monad of a stream using the supplied stateful runner function and the initial state. The state returned by an invocation of the runner is supplied as input state to the next invocation.
runStateT :: Monad m => m s -> Stream (StateT s m) a -> Stream m (s, a) Source #
Evaluate the inner monad of a stream as StateT
and emit the resulting
state and value pair after each step.
runReaderT :: Monad m => m s -> Stream (ReaderT s m) a -> Stream m a Source #
Evaluate the inner monad of a stream as ReaderT
.
withReaderT :: forall (m :: Type -> Type) r2 r1 a. Monad m => (r2 -> r1) -> Stream (ReaderT r1 m) a -> Stream (ReaderT r2 m) a Source #
Modify the environment of the underlying ReaderT monad.
evalStateT :: Monad m => m s -> Stream (StateT s m) a -> Stream m a Source #
Evaluate the inner monad of a stream as StateT
.
>>>
evalStateT s = fmap snd . Stream.runStateT s
liftInner :: forall (m :: Type -> Type) (t :: (Type -> Type) -> Type -> Type) a. (Monad m, MonadTrans t, Monad (t m)) => Stream m a -> Stream (t m) a Source #
Lift the inner monad m
of Stream m a
to t m
where t
is a monad
transformer.
localReaderT :: forall (m :: Type -> Type) r a. Monad m => (r -> r) -> Stream (ReaderT r m) a -> Stream (ReaderT r m) a Source #
Modify the environment of the underlying ReaderT monad.
foldlT :: forall (m :: Type -> Type) s b a. (Monad m, Monad (s m), MonadTrans s) => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b Source #
Lazy left fold to a transformer monad.
foldrT :: forall (m :: Type -> Type) t a b. (Monad m, Monad (t m), MonadTrans t) => (a -> t m b -> t m b) -> t m b -> Stream m a -> t m b Source #
Right fold to a transformer monad. This is the most general right fold
function. foldrS
is a special case of foldrT
, however foldrS
implementation can be more efficient:
>>>
foldrS = Stream.foldrT
>>>
step f x xs = lift $ f x (runIdentityT xs)
>>>
foldrM f z s = runIdentityT $ Stream.foldrT (step f) (lift z) s
foldrT
can be used to translate streamly streams to other transformer
monads e.g. to a different streaming type.
Pre-release
usingReaderT :: Monad m => m r -> (Stream (ReaderT r m) a -> Stream (ReaderT r m) a) -> Stream m a -> Stream m a Source #
Run a stream transformation using a given environment.
usingStateT :: Monad m => m s -> (Stream (StateT s m) a -> Stream (StateT s m) b) -> Stream m a -> Stream m b Source #
Run a stateful (StateT) stream transformation using a given state.
>>>
usingStateT s f = Stream.evalStateT s . f . Stream.liftInner
See also: scan
intercalate :: forall (m :: Type -> Type) b c. Monad m => Unfold m b c -> b -> Stream m b -> Stream m c Source #
Deprecated: Please use unfoldEachSepBySeq instead.
mergeBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a Source #
WARNING! O(n^2) time complexity wrt number of streams. Suitable for
statically fusing a small number of streams. Use the O(n) complexity
StreamK.mergeBy
otherwise.
Merge two streams using a comparison function. The head elements of both the streams are compared and the smaller of the two elements is emitted, if both elements are equal then the element from the first stream is used first.
If the streams are sorted in ascending order, the resulting stream would also remain sorted in ascending order.
>>>
s1 = Stream.fromList [1,3,5]
>>>
s2 = Stream.fromList [2,4,6,8]
>>>
Stream.fold Fold.toList $ Stream.mergeBy compare s1 s2
[1,2,3,4,5,6,8]
mergeByM :: Monad m => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a Source #
Like mergeBy
but with a monadic comparison function.
Example, to merge two streams randomly:
> randomly _ _ = randomIO >>= x -> return $ if x then LT else GT > Stream.toList $ Stream.mergeByM randomly (Stream.fromList [1,1,1,1]) (Stream.fromList [2,2,2,2]) [2,1,2,2,2,1,1,1]
Example, merge two streams in a proportion of 2:1:
>>>
:set -fno-warn-unrecognised-warning-flags
>>>
:set -fno-warn-x-partial
>>>
:{
do let s1 = Stream.fromList [1,1,1,1,1,1] s2 = Stream.fromList [2,2,2] let proportionately m n = do ref <- newIORef $ cycle $ Prelude.concat [Prelude.replicate m LT, Prelude.replicate n GT] return $ \_ _ -> do r <- readIORef ref writeIORef ref $ Prelude.tail r return $ Prelude.head r f <- proportionately 2 1 xs <- Stream.fold Fold.toList $ Stream.mergeByM f s1 s2 print xs :} [1,1,2,1,1,2,1,1,2]
roundRobin :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
Schedule the execution of two streams in a fair round-robin manner,
executing each stream once, alternately. Execution of a stream may not
necessarily result in an output, a stream may choose to Skip
producing an
element until later giving the other stream a chance to run. Therefore, this
combinator fairly interleaves the execution of two streams rather than
fairly interleaving the output of the two streams. This can be useful in
co-operative multitasking without using explicit threads. This can be used
as an alternative to async
.
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
Pre-release
interpose :: forall (m :: Type -> Type) c b. Monad m => c -> Unfold m b c -> Stream m b -> Stream m c Source #
Deprecated: Please use unfoldEachSepBy instead.
Unfold the elements of a stream, intersperse the given element between the unfolded streams and then concat them into a single stream.
Definition:
>>>
unfoldEachSepBy x = Stream.unfoldEachSepByM (return x)
>>>
unfoldEachSepBy x = Stream.intercalateSepBy Unfold.identity (Stream.repeat x)
Usage:
>>>
unwords = Stream.unfoldEachSepBy ' '
Pre-release
interposeSuffix :: forall (m :: Type -> Type) c b. Monad m => c -> Unfold m b c -> Stream m b -> Stream m c Source #
Deprecated: Please use unfoldEachEndBy instead.
Unfold the elements of a stream, append the given element after each unfolded stream and then concat them into a single stream.
Definition:
>>>
unfoldEachEndBy x = Stream.intercalateEndBy Unfold.identity (Stream.repeat x)
Usage:
>>>
unlines = Stream.unfoldEachEndBy '\n'
Pre-release
intercalateSuffix :: forall (m :: Type -> Type) b c. Monad m => Unfold m b c -> b -> Stream m b -> Stream m c Source #
Deprecated: Please use unfoldEachEndBySeq instead.
takeEndBySeq :: forall (m :: Type -> Type) a. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Stream m a -> Stream m a Source #
Take the stream until the supplied sequence is encountered. Take the sequence as well and stop.
Usage:
>>>
f pat xs = Stream.toList $ Stream.takeEndBySeq (Array.fromList pat) $ Stream.fromList xs
>>>
f "fgh" "abcdefghijk"
"abcdefgh">>>
f "lmn" "abcdefghijk"
"abcdefghijk">>>
f "" "abcdefghijk"
""
takeEndBySeq_ :: forall (m :: Type -> Type) a. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Stream m a -> Stream m a Source #
Take the stream until the supplied sequence is encountered. Do not take the sequence.
Usage:
>>>
f pat xs = Stream.toList $ Stream.takeEndBySeq_ (Array.fromList pat) $ Stream.fromList xs
>>>
f "fgh" "abcdefghijk"
"abcde">>>
f "lmn" "abcdefghijk"
"abcdefghijk">>>
f "" "abcdefghijk"
""
interleave :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
WARNING! O(n^2) time complexity wrt number of streams. Suitable for
statically fusing a small number of streams. Use the O(n) complexity
StreamK.interleave
otherwise.
Interleaves two streams, yielding one element from each stream alternately, starting from the first stream. When one stream is exhausted, all the remaining elements of the other stream are emitted in the output stream.
Both the streams are completely exhausted.
(a b c) (. . .) => a . b . c . (a b c) (. . ) => a . b . c (a b ) (. . .) => a . b . .
Examples:
>>>
f x y = Stream.toList $ Stream.interleave (Stream.fromList x) (Stream.fromList y)
>>>
f "abc" "..."
"a.b.c.">>>
f "abc" ".."
"a.b.c">>>
f "ab" "..."
"a.b.."
bfsUnfoldEach :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b Source #
Like unfoldEach
but interleaves the resulting streams in a breadth first
manner instead of appending them. Unfolds each element in the input stream
to a stream and then interleave the resulting streams.
>>>
lists = Stream.fromList [[1,4,7],[2,5,8],[3,6,9]]
>>>
Stream.toList $ Stream.bfsUnfoldEach Unfold.fromList lists
[1,2,3,4,5,6,7,8,9]
CAUTION! Do not use on infinite streams.
fairUnfoldEach :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b Source #
See fairConcatFor
for more details. This is similar except that this
uses unfolds, therefore, it is much faster due to fusion.
>>>
:{
outerLoop = Stream.fromList [1,2,3] innerLoop = Unfold.carry $ Unfold.lmap (const [4,5,6]) Unfold.fromList :}
>>>
Stream.toList $ Stream.fairUnfoldEach innerLoop outerLoop
[(1,4),(1,5),(2,4),(1,6),(2,5),(3,4),(2,6),(3,5),(3,6)]
unfoldEachSepBySeq :: forall (m :: Type -> Type) b c. Monad m => b -> Unfold m b c -> Stream m b -> Stream m c Source #
Unfold each element of the stream, separate the successive unfolds by a sequence generated by unfolding the supplied value.
Definition:
>>>
unfoldEachSepBySeq a u = Stream.unfoldEach u . Stream.intersperse a
>>>
unfoldEachSepBySeq a u = Stream.intercalateSepBy u (Stream.repeat a) u
Idioms:
>>>
intersperse x = Stream.unfoldEachSepBySeq x Unfold.identity
>>>
unwords = Stream.unfoldEachSepBySeq " " Unfold.fromList
Usage:
>>>
input = Stream.fromList ["abc", "def", "ghi"]
>>>
Stream.toList $ Stream.unfoldEachSepBySeq " " Unfold.fromList input
"abc def ghi"
unfoldEachEndBySeq :: forall (m :: Type -> Type) b c. Monad m => b -> Unfold m b c -> Stream m b -> Stream m c Source #
Unfold each element of the stream, end each unfold by a sequence generated by unfolding the supplied value.
Definition:
>>>
unfoldEachEndBySeq a u = Stream.unfoldEach u . Stream.intersperseEndByM a
>>>
unfoldEachEndBySeq a u = Stream.intercalateEndBy u (Stream.repeat a) u
Idioms:
>>>
intersperseEndByM x = Stream.unfoldEachEndBySeq x Unfold.identity
>>>
unlines = Stream.unfoldEachEndBySeq "\n" Unfold.fromList
Usage:
>>>
input = Stream.fromList ["abc", "def", "ghi"]
>>>
Stream.toList $ Stream.unfoldEachEndBySeq "\n" Unfold.fromList input
"abc\ndef\nghi\n"
fairConcatMap :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b) -> Stream m a -> Stream m b Source #
See fairConcatFor
for documentation.
fairConcatFor :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> (a -> Stream m b) -> Stream m b Source #
fairConcatFor
is like concatFor
but traverses the depth and breadth of
nesting equally. Therefore, the outer and the inner loops in a nested loop
get equal priority. It can be used to nest infinite streams without starving
outer streams due to inner ones.
Given a stream of three streams:
1. [1,2,3] 2. [4,5,6] 3. [7,8,9]
Here, outer loop is the stream of streams and the inner loops are the
individual streams. The traversal sweeps the diagonals in the above grid to
give equal chance to outer and inner loops. The resulting stream is
(1),(2,4),(3,5,7),(6,8),(9)
, diagonals are parenthesized for emphasis.
Looping
A single stream case is equivalent to concatFor
:
>>>
Stream.toList $ Stream.fairConcatFor (Stream.fromList [1,2]) $ \x -> Stream.fromPure x
[1,2]
Fair Nested Looping
Multiple streams nest like for
loops. The result is a cross product of the
streams. However, the ordering of the results of the cross product is such
that each stream gets consumed equally. In other words, inner iterations of
a nested loop get the same priority as the outer iterations. Inner
iterations do not finish completely before the outer iterations start.
>>>
:{
Stream.toList $ do Stream.fairConcatFor (Stream.fromList [1,2,3]) $ \x -> Stream.fairConcatFor (Stream.fromList [4,5,6]) $ \y -> Stream.fromPure (x, y) :} [(1,4),(1,5),(2,4),(1,6),(2,5),(3,4),(2,6),(3,5),(3,6)]
Nesting Infinite Streams
Example with infinite streams. Print all pairs in the cross product with sum less than a specified number.
>>>
:{
Stream.toList $ Stream.takeWhile (\(x,y) -> x + y < 6) $ Stream.fairConcatFor (Stream.fromList [1..]) $ \x -> Stream.fairConcatFor (Stream.fromList [1..]) $ \y -> Stream.fromPure (x, y) :} [(1,1),(1,2),(2,1),(1,3),(2,2),(3,1),(1,4),(2,3),(3,2),(4,1)]
How the nesting works?
If we look at the cross product of [1,2,3], [4,5,6], the streams being
combined using fairConcatFor
are the following sequential loop iterations:
(1,4) (1,5) (1,6) -- first iteration of the outer loop (2,4) (2,5) (2,6) -- second iteration of the outer loop (3,4) (3,5) (3,6) -- third iteration of the outer loop
The result is a triangular or diagonal traversal of these iterations:
[(1,4),(1,5),(2,4),(1,6),(2,5),(3,4),(2,6),(3,5),(3,6)]
Non-Termination Cases
If one of the two interleaved streams does not produce an output at all and continues forever then the other stream will never get scheduled. This is because a stream is unscheduled only after it produces an output. This can lead to non-terminating programs, an example is provided below.
>>>
:{
oddsIf x = Stream.fromList (if x then [1,3..] else [2,4..]) filterEven x = if even x then Stream.fromPure x else Stream.nil :}
>>>
:{
evens = Stream.fairConcatFor (Stream.fromList [True,False]) $ \r -> Stream.concatFor (oddsIf r) filterEven :}
The evens
function does not terminate because, when r is True, the nested
concatFor
is a non-productive infinite loop, therefore, the outer loop
never gets a chance to generate the False
value.
But the following refactoring of the above code works as expected:
>>>
:{
mixed = Stream.fairConcatFor (Stream.fromList [True,False]) $ \r -> Stream.concatFor (oddsIf r) Stream.fromPure :}
>>>
evens = Stream.fairConcatFor mixed filterEven
>>>
Stream.toList $ Stream.take 3 $ evens
[2,4,6]
This works because in mixed
both the streams being interleaved are
productive.
Care should be taken how you write your program, keep in mind the scheduling
implications. To avoid such scheduling problems in serial interleaving, you
can use fairSchedFor
or concurrent scheduling i.e. parFairConcatFor. Due
to concurrent scheduling the other branch will make progress even if one is
an infinite loop producing nothing.
Logic Programming
Streamly provides all operations for logic programming. It provides
functionality equivalent to LogicT
type from the logict
package.
The MonadLogic
operations can be implemented using the available stream
operations. For example, uncons
is msplit
, interleave
corresponds to
the interleave
operation of MonadLogic, fairConcatFor
is the
fair bind (>>-
) operation. fairSchedFor
is an even better alternative
for fair bind, it guarantees that non-productive infinite streams cannot
block progress.
Related Operations
See also "Streamly.Internal.Data.StreamK.fairConcatFor".
fairConcatForM :: Monad m => Stream m a -> (a -> m (Stream m b)) -> Stream m b Source #
See fairConcatFor
for documentation.
parseMany :: forall (m :: Type -> Type) a b. Monad m => Parser a m b -> Stream m a -> Stream m (Either ParseError b) Source #
Apply a Parser
repeatedly on a stream and emit the parsed values in the
output stream.
Usage:
>>>
s = Stream.fromList [1..10]
>>>
parser = Parser.takeBetween 0 2 Fold.sum
>>>
Stream.toList $ Stream.parseMany parser s
[Right 3,Right 7,Right 11,Right 15,Right 19]
This is the streaming equivalent of the many
parse
combinator.
Known Issues: When the parser fails there is no way to get the remaining stream.
splitSepBySeq_ :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Fold m a b -> Stream m a -> Stream m b Source #
Like splitSepBy_
but splits the stream on a sequence of elements rather than
a single element. Parses a sequence of tokens separated by an infixed
separator e.g. a;b;c
is parsed as a
, b
, c
. If the pattern is empty
then each element is a match, thus the fold is finalized on each element.
>>>
splitSepBy p xs = Stream.fold Fold.toList $ Stream.splitSepBySeq_ (Array.fromList p) Fold.toList (Stream.fromList xs)
>>>
splitSepBy "" ""
[]
>>>
splitSepBy "" "a...b"
["a",".",".",".","b"]
>>>
splitSepBy ".." ""
[]
>>>
splitSepBy ".." "a...b"
["a",".b"]
>>>
splitSepBy ".." "abc"
["abc"]
>>>
splitSepBy ".." ".."
["",""]
>>>
splitSepBy "." ".a"
["","a"]
>>>
splitSepBy "." "a."
["a",""]
Uses Rabin-Karp algorithm for substring search.
splitEndBySeq :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Fold m a b -> Stream m a -> Stream m b Source #
Parses a sequence of tokens suffixed by a separator e.g. a;b;c;
is
parsed as a;
, b;
, c;
. If the pattern is empty the input stream is
returned as it is.
Equivalent to the following:
>>>
splitEndBySeq pat f = Stream.foldMany (Fold.takeEndBySeq pat f)
Usage:
>>>
f p = Stream.splitEndBySeq (Array.fromList p) Fold.toList
>>>
splitEndBy p xs = Stream.fold Fold.toList $ f p (Stream.fromList xs)
>>>
splitEndBy "" ""
[]
>>>
splitEndBy "" "a...b"
["a",".",".",".","b"]
>>>
splitEndBy ".." ""
[]
>>>
splitEndBy ".." "a...b"
["a..",".b"]
>>>
splitEndBy ".." "abc"
["abc"]
>>>
splitEndBy ".." ".."
[".."]
>>>
splitEndBy "." ".a"
[".","a"]
>>>
splitEndBy "." "a."
["a."]
Uses Rabin-Karp algorithm for substring search.
splitEndBySeq_ :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Fold m a b -> Stream m a -> Stream m b Source #
Like splitEndBySeq
but drops the separators and returns only the tokens.
Equivalent to the following:
>>>
splitEndBySeq_ pat f = Stream.foldMany (Fold.takeEndBySeq_ pat f)
Usage:
>>>
f p = Stream.splitEndBySeq_ (Array.fromList p) Fold.toList
>>>
splitEndBy_ p xs = Stream.fold Fold.toList $ f p (Stream.fromList xs)
>>>
splitEndBy_ "" ""
[]
>>>
splitEndBy_ "" "a...b"
["a",".",".",".","b"]
>>>
splitEndBy_ ".." ""
[]
>>>
splitEndBy_ ".." "a...b"
["a",".b"]
>>>
splitEndBy_ ".." "abc"
["abc"]
>>>
splitEndBy_ ".." ".."
[""]
>>>
splitEndBy_ "." ".a"
["","a"]
>>>
splitEndBy_ "." "a."
["a"]
Uses Rabin-Karp algorithm for substring search.
wordsBy :: forall (m :: Type -> Type) a b. Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b Source #
Split the stream after stripping leading, trailing, and repeated separators determined by the predicate supplied. The tokens after splitting are collected by the supplied fold. In other words, the tokens are parsed in the same way as words are parsed from whitespace separated text.
>>>
f x = Stream.toList $ Stream.wordsBy (== '.') Fold.toList $ Stream.fromList x
>>>
f "a.b"
["a","b"]>>>
f "a..b"
["a","b"]>>>
f ".a..b."
["a","b"]
parseManyPos :: forall (m :: Type -> Type) a b. Monad m => Parser a m b -> Stream m a -> Stream m (Either ParseErrorPos b) Source #
Like parseMany
but includes stream position information in the error
messages.
parseIterate :: forall (m :: Type -> Type) b a. Monad m => (b -> Parser a m b) -> b -> Stream m a -> Stream m (Either ParseError b) Source #
Iterate a parser generating function on a stream. The initial value b
is
used to generate the first parser, the parser is applied on the stream and
the result is used to generate the next parser and so on.
Example:
>>>
import Data.Monoid (Sum(..))
>>>
s = Stream.fromList [1..10]
>>>
Stream.toList $ fmap getSum $ Stream.catRights $ Stream.parseIterate (\b -> Parser.takeBetween 0 2 (Fold.sconcat b)) (Sum 0) $ fmap Sum s
[3,10,21,36,55,55]
This is the streaming equivalent of monad like sequenced application of parsers where next parser is dependent on the previous parser.
Pre-release
parseIteratePos :: forall (m :: Type -> Type) b a. Monad m => (b -> Parser a m b) -> b -> Stream m a -> Stream m (Either ParseErrorPos b) Source #
Like parseIterate
but includes stream position information in the error
messages.
data InterleaveState s1 s2 Source #
Constructors
InterleaveFirst s1 s2 | |
InterleaveSecond s1 s2 | |
InterleaveSecondOnly s2 | |
InterleaveFirstOnly s1 |
interleaveEndBy' :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
Interleave the two streams such that the elements of the second stream are ended by the elements of the first stream. If one of the streams is exhausted then interleaving stops.
(. . .) (a b c) => a . b . c . (. . ) (a b c) => a . b . -- c is discarded (. . .) (a b ) => a . b . -- . is discarded
Examples:
>>>
f x y = Stream.toList $ Stream.interleaveEndBy' (Stream.fromList x) (Stream.fromList y)
>>>
f "..." "abc"
"a.b.c.">>>
f ".." "abc"
"a.b.">>>
f "..." "ab"
"a.b."
Definition:
>>>
interleaveEndBy' s1 s2 = Stream.unfoldEach Unfold.fromTuple $ Stream.zipWith (,) s2 s1
Similarly, we can defined interleaveBeginBy' as:
>>>
interleaveBeginBy' = flip interleaveEndBy'
interleaveSepBy' :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
Interleave the two streams such that the elements of the first stream are infixed between the elements of the second stream. If one of the streams is exhausted then interleaving stops.
(. . .) (a b c) => a . b . c -- additional . is discarded (. . ) (a b c) => a . b . c (. ) (a b c) => a . b -- c is discarded
>>>
f x y = Stream.toList $ Stream.interleaveSepBy' (Stream.fromList x) (Stream.fromList y)
>>>
f "..." "abc"
"a.b.c">>>
f ".." "abc"
"a.b.c">>>
f "." "abc"
"a.b"
interleaveBeginBy :: forall (m :: Type -> Type) a. Stream m a -> Stream m a -> Stream m a Source #
Interleave the two streams such that the elements of the second stream are prefixed by the elements of the first stream. Interleaving stops when and only when the second stream is exhausted. Shortfall of the prefix stream is ignored and excess is discarded.
(. . .) (a b c) => . a . b . c (. . .) (a b ) => . a . b -- additional . is discarded (. . ) (a b c) => . a . b c -- missing . is ignored
Unimplemented
interleaveEndBy :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
Like interleaveEndBy'
but interleaving stops when and only when the
second stream is exhausted. Shortfall of the suffix stream is ignored and
excess is discarded.
(. . .) (a b c) => a . b . c . (. . ) (a b c) => a . b . c -- missing . is ignored (. . .) (a b ) => a . b . -- additional . is discarded
>>>
f x y = Stream.toList $ Stream.interleaveEndBy (Stream.fromList x) (Stream.fromList y)
>>>
f "..." "abc"
"a.b.c.">>>
f ".." "abc"
"a.b.c">>>
f "..." "ab"
"a.b."
interleaveSepBy :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
Like interleaveSepBy'
but interleaving stops when and only when the
second stream is exhausted. Shortfall of the infix stream is ignored and
excess is discarded.
(. . .) (a b c) => a . b . c -- additional . is discarded (. . ) (a b c) => a . b . c (. ) (a b c) => a . b c -- missing . is ignored
Examples:
>>>
f x y = Stream.toList $ Stream.interleaveSepBy (Stream.fromList x) (Stream.fromList y)
>>>
f "..." "abc"
"a.b.c">>>
f ".." "abc"
"a.b.c">>>
f "." "abc"
"a.bc"
mergeMinBy :: (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a Source #
Like mergeByM
but stops merging as soon as any of the two streams stops.
Unimplemented
mergeFstBy :: (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a Source #
Like mergeByM
but stops merging as soon as the first stream stops.
Unimplemented
unfoldEachFoldBy :: forall (m :: Type -> Type) b c a. Fold m b c -> Unfold m a b -> Stream m a -> Stream m c Source #
Stream must be finite. Unfolds each element of the input stream to generate streams. After generating one element from each stream fold those using the supplied fold and emit the result in the output stream. Continue doing this until the streams are exhausted.
Unimplemented
data ConcatUnfoldInterleaveState o i Source #
Constructors
ConcatUnfoldInterleaveOuter o [i] | |
ConcatUnfoldInterleaveInner o [i] | |
ConcatUnfoldInterleaveInnerL [i] [i] | |
ConcatUnfoldInterleaveInnerR [i] [i] |
altBfsUnfoldEach :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b Source #
Like bfsUnfoldEach
but reverses the traversal direction after reaching
the last stream and then after reaching the first stream, thus alternating
the directions. This could be a little bit more efficient if the order of
traversal is not important.
>>>
lists = Stream.fromList [[1,4,7],[2,5,8],[3,6,9]]
>>>
Stream.toList $ Stream.altBfsUnfoldEach Unfold.fromList lists
[1,2,3,6,5,4,7,8,9]
CAUTION! Do not use on infinite streams.
unfoldEachSepBy :: forall (m :: Type -> Type) c b. Monad m => c -> Unfold m b c -> Stream m b -> Stream m c Source #
Unfold the elements of a stream, intersperse the given element between the unfolded streams and then concat them into a single stream.
Definition:
>>>
unfoldEachSepBy x = Stream.unfoldEachSepByM (return x)
>>>
unfoldEachSepBy x = Stream.intercalateSepBy Unfold.identity (Stream.repeat x)
Usage:
>>>
unwords = Stream.unfoldEachSepBy ' '
Pre-release
unfoldEachSepByM :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c Source #
Monadic variant of unfoldEachSepBy
.
Definition:
>>>
unfoldEachSepByM x = Stream.intercalateSepBy Unfold.identity (Stream.repeatM x)
unfoldEachEndBy :: forall (m :: Type -> Type) c b. Monad m => c -> Unfold m b c -> Stream m b -> Stream m c Source #
Unfold the elements of a stream, append the given element after each unfolded stream and then concat them into a single stream.
Definition:
>>>
unfoldEachEndBy x = Stream.intercalateEndBy Unfold.identity (Stream.repeat x)
Usage:
>>>
unlines = Stream.unfoldEachEndBy '\n'
Pre-release
unfoldEachEndByM :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c Source #
Monadic variant of unfoldEachEndBy
.
Definition:
>>>
unfoldEachEndByM x = Stream.intercalateEndBy Unfold.identity (Stream.repeatM x)
intercalateSepBy :: forall (m :: Type -> Type) b c a. Monad m => Unfold m b c -> Stream m b -> Unfold m a c -> Stream m a -> Stream m c Source #
The first stream Stream m b
is turned into a stream of streams by
unfolding each element using the first unfold, similarly Stream m a
is
also turned into a stream of streams. The second stream of streams is
interspersed with the streams from the first stream in an infix manner and
then the resulting stream is flattened.
You can think of this as interleaveSepBy
on the stream of streams followed
by concat. Same as the following but more efficient:
>>>
intercalateSepBy u1 s1 u2 s2 = Stream.concat $ Stream.interleaveSepBy (fmap (Stream.unfold u1) s1) (fmap (Stream.unfold u2) s2)
If the separator stream consists of nil streams then it becomes equivalent
to unfoldEach
:
>>>
unfoldEach = Stream.intercalateSepBy (Unfold.nilM (const (return ()))) (Stream.repeat ())
Pre-release
intercalateEndBy :: forall (m :: Type -> Type) a c b. Monad m => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c Source #
See intercalateSepBy
for detailed documentation.
You can think of this as interleaveEndBy
on the stream of streams followed
by concat. Same as the following but more efficient:
>>>
intercalateEndBy u1 s1 u2 s2 = Stream.concat $ Stream.interleaveEndBy (fmap (Stream.unfold u1) s1) (fmap (Stream.unfold u2) s2)
Pre-release
fairConcatMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b Source #
See fairConcatFor
for documentation.
unfoldSched :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b Source #
Similar to bfsUnfoldEach
but scheduling is independent of output.
This is an N-ary version of roundRobin
.
>>>
lists = Stream.fromList [[1,4,7],[2,5,8],[3,6,9]]
>>>
Stream.toList $ Stream.unfoldSched Unfold.fromList lists
[1,2,3,4,5,6,7,8,9]
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
CAUTION! Do not use on infinite streams.
fairUnfoldSched :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b Source #
Similar to fairUnfoldEach
but scheduling is independent of the output.
>>>
:{
outerLoop = Stream.fromList [1,2,3] innerLoop = Unfold.carry $ Unfold.lmap (const [4,5,6]) Unfold.fromList :}
>>>
Stream.toList $ Stream.fairUnfoldSched innerLoop outerLoop
[(1,4),(1,5),(2,4),(1,6),(2,5),(3,4),(2,6),(3,5),(3,6)]
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
schedMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b Source #
Round robin co-operative scheduling of multiple streams.
Like concatMap but schedules the generated streams in a round robin fashion. Note that it does not strive to interleave the outputs of the streams, just gives the streams a chance to run whether it produces an output or not. Therefore, the outputs may not seem to be fairly interleaved if a stream decides to skip the output.
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
CAUTION! Do not use on infinite streams.
schedMap :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b) -> Stream m a -> Stream m b Source #
See SchedFor
for documentation.
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
CAUTION! Do not use on infinite streams.
fairSchedMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b Source #
See fairSchedFor
for documentation.
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
fairSchedMap :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b) -> Stream m a -> Stream m b Source #
See fairSchedFor
for documentation.
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
schedForM :: Monad m => Stream m a -> (a -> m (Stream m b)) -> Stream m b Source #
See SchedFor
for documentation.
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
CAUTION! Do not use on infinite streams.
schedFor :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> (a -> Stream m b) -> Stream m b Source #
Similar to bfsConcatFor
but scheduling is independent of output.
>>>
lists = Stream.fromList [[1,4,7],[2,5,8],[3,6,9]]
>>>
Stream.toList $ Stream.schedFor lists $ \xs -> Stream.fromList xs
[1,2,3,4,5,6,7,8,9]
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
CAUTION! Do not use on infinite streams.
fairSchedForM :: Monad m => Stream m a -> (a -> m (Stream m b)) -> Stream m b Source #
See fairSchedFor
for documentation.
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
fairSchedFor :: forall (m :: Type -> Type) a b. Monad m => Stream m a -> (a -> Stream m b) -> Stream m b Source #
fairSchedFor
is just like fairConcatFor
, it traverses the depth and
breadth of nesting equally. It maintains fairness among different levels of
loop iterations. Therefore, the outer and the inner loops in a nested loop
get equal priority. It can be used to nest infinite streams without starving
outer streams due to inner ones.
There is one crucial difference, while fairConcatFor
necessarily produces
an output from one stream before it schedules the next, fairSchedFor
schedules the next stream even if a stream did not produce an output. Thus
it interleaves the CPU rather than the outputs of the streams. Thus even if
an infinite stream does not produce an output it can not block all other
streams.
Note that the order of emitting the output from different streams may not be predictable, it depends on the skip points inside the stream. Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
Non-Productive Streams
Unlike in fairConcatFor
, if one of the two interleaved streams does not
produce an output at all and continues forever then the other stream will
still get scheduled. The following program will hang forever for
fairConcatFor
but will work fine with fairSchedFor
.
>>>
:{
oddsIf x = Stream.fromList (if x then [1,3..] else [2,4..]) filterEven x = if even x then Stream.fromPure x else Stream.nil :}
>>>
:{
evens = Stream.fairSchedFor (Stream.fromList [True,False]) $ \r -> Stream.fairSchedFor (oddsIf r) filterEven :}
>>>
Stream.toList $ Stream.take 3 $ evens
[2,4,6]
When r
is True, the nested fairSchedFor
is a non-productive infinite
loop, but still the outer loop gets a chance to generate the False
value,
and the evens
function can produce output. The same code won't terminate
if we use fairConcatFor
instead of fairSchedFor
. Thus even without
explicit concurrency we can schedule multiple streams on the same CPU.
Logic Programming
When exploring large streams in logic programming, fairSchedFor
can be
used as a safe alternative to fairConcatFor
as it cannot block due to
non-productive infinite streams.
foldSequence :: forall (m :: Type -> Type) a b. Stream m (Fold m a b) -> Stream m a -> Stream m b Source #
Apply a stream of folds to an input stream and emit the results in the output stream.
Unimplemented
foldIterateM :: Monad m => (b -> m (Fold m a b)) -> m b -> Stream m a -> Stream m b Source #
Iterate a fold generator on a stream. The initial value b
is used to
generate the first fold, the fold is applied on the stream and the result of
the fold is used to generate the next fold and so on.
Usage:
>>>
import Data.Monoid (Sum(..))
>>>
f x = return (Fold.take 2 (Fold.sconcat x))
>>>
s = fmap Sum $ Stream.fromList [1..10]
>>>
Stream.fold Fold.toList $ fmap getSum $ Stream.foldIterateM f (pure 0) s
[3,10,21,36,55,55]
This is the streaming equivalent of monad like sequenced application of folds where next fold is dependent on the previous fold.
Pre-release
parseSequence :: forall (m :: Type -> Type) a b. Stream m (Parser a m b) -> Stream m a -> Stream m b Source #
Apply a stream of parsers to an input stream and emit the results in the output stream.
Unimplemented
parseManyTill :: forall a (m :: Type -> Type) b x. Parser a m b -> Parser a m x -> Stream m a -> Stream m b Source #
parseManyTill collect test stream
tries the parser test
on the input,
if test
fails it backtracks and tries collect
, after collect
succeeds
test
is tried again and so on. The parser stops when test
succeeds. The
output of test
is discarded and the output of collect
is emitted in the
output stream. The parser fails if collect
fails.
Unimplemented
groupsWhile :: forall (m :: Type -> Type) a b. Monad m => (a -> a -> Bool) -> Fold m a b -> Stream m a -> Stream m b Source #
Keep collecting items in a group as long as the comparison function
returns true. The comparison function is cmp old new
where old
is the
first item in the group and new
is the incoming item being tested for
membership of the group. The collected items are folded by the supplied
fold.
Definition:
>>>
groupsWhile cmp f = Stream.parseMany (Parser.groupBy cmp f)
groupsRollingBy :: forall (m :: Type -> Type) a b. Monad m => (a -> a -> Bool) -> Fold m a b -> Stream m a -> Stream m b Source #
Definition:
>>>
groupsRollingBy cmp f = Stream.parseMany (Parser.groupByRolling cmp f)
splitOnSuffixSeq :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Bool -> Array a -> Fold m a b -> Stream m a -> Stream m b Source #
splitOnSuffixSeq withSep pat fld input
splits the input using pat
as a
suffixed separator, the resulting split segments are fed to the fold fld
.
If withSep
is True then the separator sequence is also suffixed with the
split segments.
Internal
splitBeginBy_ :: forall a (m :: Type -> Type) b. (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b Source #
Split on a prefixed separator element, dropping the separator. The
supplied Fold
is applied on the split segments.
> splitOnPrefix' p xs = Stream.toList $ Stream.splitOnPrefix p (Fold.toList) (Stream.fromList xs)
> splitOnPrefix' (== .
) ".a.b"
["a","b"]
An empty stream results in an empty output stream:
> splitOnPrefix' (==
.
) ""
[]
An empty segment consisting of only a prefix is folded to the default output of the fold:
> splitOnPrefix' (==.
) "." [""] > splitOnPrefix' (==.
) ".a.b." ["a","b",""] > splitOnPrefix' (==.
) ".a..b" ["a","","b"]
A prefix is optional at the beginning of the stream:
> splitOnPrefix' (==.
) "a" ["a"] > splitOnPrefix' (==.
) "a.b" ["a","b"]
splitOnPrefix
is an inverse of intercalatePrefix
with a single element:
Stream.intercalatePrefix (Stream.fromPure '.') Unfold.fromList . Stream.splitOnPrefix (== '.') Fold.toList === id
Assuming the input stream does not contain the separator:
Stream.splitOnPrefix (== '.') Fold.toList . Stream.intercalatePrefix (Stream.fromPure '.') Unfold.fromList === id
Unimplemented
splitEndBySeqOneOf :: forall a (m :: Type -> Type) b. [Array a] -> Fold m a b -> Stream m a -> Stream m b Source #
Split post any one of the given patterns.
Unimplemented
splitSepBySeqOneOf :: forall a (m :: Type -> Type) b. [Array a] -> Fold m a b -> Stream m a -> Stream m b Source #
Split on any one of the given patterns.
Unimplemented
splitInnerBy :: Monad m => (f a -> m (f a, Maybe (f a))) -> (f a -> f a -> m (f a)) -> Stream m (f a) -> Stream m (f a) Source #
Performs infix separator style splitting.
splitInnerBySuffix :: Monad m => (f a -> Bool) -> (f a -> m (f a, Maybe (f a))) -> (f a -> f a -> m (f a)) -> Stream m (f a) -> Stream m (f a) Source #
Performs infix separator style splitting.
dropPrefix :: forall (m :: Type -> Type) a. Stream m a -> Stream m a -> Stream m a Source #
Drop prefix from the input stream if present.
Space: O(1)
See also stripPrefix.
Unimplemented
dropInfix :: forall (m :: Type -> Type) a. Stream m a -> Stream m a -> Stream m a Source #
Drop all matching infix from the input stream if present. Infix stream may be consumed multiple times.
Space: O(n)
where n is the length of the infix.
See also stripInfix.
Unimplemented
dropSuffix :: forall (m :: Type -> Type) a. Stream m a -> Stream m a -> Stream m a Source #
Drop suffix from the input stream if present. Suffix stream may be consumed multiple times.
Space: O(n)
where n is the length of the suffix.
See also stripSuffix.
Unimplemented
interposeM :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c Source #
Deprecated: Please use unfoldEachSepByM instead.
Monadic variant of unfoldEachSepBy
.
Definition:
>>>
unfoldEachSepByM x = Stream.intercalateSepBy Unfold.identity (Stream.repeatM x)
interposeSuffixM :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c Source #
Deprecated: Please use unfoldEachEndByM instead.
Monadic variant of unfoldEachEndBy
.
Definition:
>>>
unfoldEachEndByM x = Stream.intercalateEndBy Unfold.identity (Stream.repeatM x)
gintercalate :: forall (m :: Type -> Type) a c b. Monad m => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c Source #
Deprecated: Please use intercalateSepBy instead.
>>>
gintercalate u1 s1 u2 s2 = Stream.intercalateSepBy u2 s2 u1 s1
gintercalateSuffix :: forall (m :: Type -> Type) a c b. Monad m => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c Source #
Deprecated: Please use intercalateEndBy instead. Note the change in argument order.
>>>
gintercalateSuffix u1 s1 u2 s2 = Stream.intercalateEndBy u2 s2 u1 s1
unfoldInterleave :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b Source #
Deprecated: Please use altBfsUnfoldEach instead.
Like bfsUnfoldEach
but reverses the traversal direction after reaching
the last stream and then after reaching the first stream, thus alternating
the directions. This could be a little bit more efficient if the order of
traversal is not important.
>>>
lists = Stream.fromList [[1,4,7],[2,5,8],[3,6,9]]
>>>
Stream.toList $ Stream.altBfsUnfoldEach Unfold.fromList lists
[1,2,3,6,5,4,7,8,9]
CAUTION! Do not use on infinite streams.
unfoldRoundRobin :: forall (m :: Type -> Type) a b. Monad m => Unfold m a b -> Stream m a -> Stream m b Source #
Deprecated: Please use unfoldSched instead.
Similar to bfsUnfoldEach
but scheduling is independent of output.
This is an N-ary version of roundRobin
.
>>>
lists = Stream.fromList [[1,4,7],[2,5,8],[3,6,9]]
>>>
Stream.toList $ Stream.unfoldSched Unfold.fromList lists
[1,2,3,4,5,6,7,8,9]
Scheduling is affected by the Skip constructor; implementations with more skips receive proportionally less scheduling time.
CAUTION! Do not use on infinite streams.
interleaveMin :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
Deprecated: Please use flip interleaveEndBy' instead.
Like interleave
but stops interleaving as soon as any of the two streams
stops. The suffix Min
in the name determines the stop behavior.
This is the same as interleaveEndBy' but it might emit an additional element at the end.
interleaveFst :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
Deprecated: Please use flip interleaveSepBy instead.
interleaveFstSuffix :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a -> Stream m a Source #
Deprecated: Please use flip interleaveEndBy instead.
parseManyD :: forall (m :: Type -> Type) a b. Monad m => Parser a m b -> Stream m a -> Stream m (Either ParseError b) Source #
Deprecated: Please use parseMany instead.
parseIterateD :: forall (m :: Type -> Type) b a. Monad m => (b -> Parser a m b) -> b -> Stream m a -> Stream m (Either ParseError b) Source #
Deprecated: Please use parseIterate instead.
groupsBy :: forall (m :: Type -> Type) a b. Monad m => (a -> a -> Bool) -> Fold m a b -> Stream m a -> Stream m b Source #
Deprecated: Please use groupsWhile instead. Please note the change in the argument order of the comparison function.
The argument order of the comparison function in groupsWhile
is
different than that of groupsBy
.
In groupsBy
the comparison function takes the next element as the first
argument and the previous element as the second argument. In groupsWhile
the first argument is the previous element and second argument is the next
element.
splitOnSeq :: forall (m :: Type -> Type) a b. (MonadIO m, Unbox a, Enum a, Eq a) => Array a -> Fold m a b -> Stream m a -> Stream m b Source #
Deprecated: Please use splitSepBySeq_ instead.
Like splitSepBy_
but splits the stream on a sequence of elements rather than
a single element. Parses a sequence of tokens separated by an infixed
separator e.g. a;b;c
is parsed as a
, b
, c
. If the pattern is empty
then each element is a match, thus the fold is finalized on each element.
>>>
splitSepBy p xs = Stream.fold Fold.toList $ Stream.splitSepBySeq_ (Array.fromList p) Fold.toList (Stream.fromList xs)
>>>
splitSepBy "" ""
[]
>>>
splitSepBy "" "a...b"
["a",".",".",".","b"]
>>>
splitSepBy ".." ""
[]
>>>
splitSepBy ".." "a...b"
["a",".b"]
>>>
splitSepBy ".." "abc"
["abc"]
>>>
splitSepBy ".." ".."
["",""]
>>>
splitSepBy "." ".a"
["","a"]
>>>
splitSepBy "." "a."
["a",""]
Uses Rabin-Karp algorithm for substring search.
mapMaybe :: forall (m :: Type -> Type) a b. Monad m => (a -> Maybe b) -> Stream m a -> Stream m b Source #
sequence :: Monad m => Stream m (m a) -> Stream m a Source #
>>>
sequence = Stream.mapM id
Replace the elements of a stream of monadic actions with the outputs of those actions.
>>>
s = Stream.fromList [putStr "a", putStr "b", putStrLn "c"]
>>>
Stream.fold Fold.drain $ Stream.sequence s
abc
with :: forall (m :: Type -> Type) a s b. Monad m => (Stream m a -> Stream m (s, a)) -> (((s, a) -> b) -> Stream m (s, a) -> Stream m (s, a)) -> ((s, a) -> b) -> Stream m a -> Stream m a Source #
Modify a Stream m a -> Stream m a
stream transformation that accepts a
predicate (a -> b)
to accept ((s, a) -> b)
instead, provided a
transformation Stream m a -> Stream m (s, a)
. Convenient to filter with
index or time.
>>>
filterWithIndex = Stream.with Stream.indexed Stream.filter
Pre-release
filter :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a Source #
Include only those elements that pass a predicate.
>>>
filter p = Stream.filterM (return . p)
>>>
filter p = Stream.mapMaybe (\x -> if p x then Just x else Nothing)
>>>
filter p = Stream.postscanlMaybe (Scanl.filtering p)
trace :: Monad m => (a -> m b) -> Stream m a -> Stream m a Source #
Apply a monadic function to each element flowing through the stream and discard the results.
>>>
s = Stream.enumerateFromTo 1 2
>>>
Stream.fold Fold.drain $ Stream.trace print s
1 2
Compare with tap
.
scanl :: forall (m :: Type -> Type) a b. Monad m => Scanl m a b -> Stream m a -> Stream m b Source #
Strict left scan. Scan a stream using the given fold. Scan includes
the initial (default) value of the accumulator as well as the final value.
Compare with postscan
which omits the initial value.
>>>
s = Stream.fromList [1..10]
>>>
Stream.fold Fold.toList $ Stream.takeWhile (< 10) $ Stream.scanl Scanl.sum s
[0,1,3,6]
See also: usingStateT
scanl1 :: forall (m :: Type -> Type) a. Monad m => (a -> a -> a) -> Stream m a -> Stream m a Source #
scanl' :: forall (m :: Type -> Type) b a. Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b Source #
Strict left scan. Like map
, scanl'
too is a one to one transformation,
however it adds an extra element.
>>>
Stream.toList $ Stream.scanl' (+) 0 $ Stream.fromList [1,2,3,4]
[0,1,3,6,10]
>>>
Stream.toList $ Stream.scanl' (flip (:)) [] $ Stream.fromList [1,2,3,4]
[[],[1],[2,1],[3,2,1],[4,3,2,1]]
The output of scanl'
is the initial value of the accumulator followed by
all the intermediate steps and the final result of foldl'
.
By streaming the accumulated state after each fold step, we can share the state across multiple stages of stream composition. Each stage can modify or extend the state, do some processing with it and emit it for the next stage, thus modularizing the stream processing. This can be useful in stateful or event-driven programming.
Consider the following monolithic example, computing the sum and the product
of the elements in a stream in one go using a foldl'
:
>>>
Stream.fold (Fold.foldl' (\(s, p) x -> (s + x, p * x)) (0,1)) $ Stream.fromList [1,2,3,4]
(10,24)
Using scanl'
we can make it modular by computing the sum in the first
stage and passing it down to the next stage for computing the product:
>>>
:{
Stream.fold (Fold.foldl' (\(_, p) (s, x) -> (s, p * x)) (0,1)) $ Stream.scanl' (\(s, _) x -> (s + x, x)) (0,1) $ Stream.fromList [1,2,3,4] :} (10,24)
IMPORTANT: scanl'
evaluates the accumulator to WHNF. To avoid building
lazy expressions inside the accumulator, it is recommended that a strict
data structure is used for accumulator.
>>>
scanl' step z = Stream.scanl (Scanl.mkScanl step z)
>>>
scanl' f z xs = Stream.scanlM' (\a b -> return (f a b)) (return z) xs
See also: usingStateT
scanr :: forall (m :: Type -> Type) a b. Monad m => Scanr m a b -> Stream m a -> Stream m b Source #
Use a lazy right Scanr
to transform a stream.
The following example extracts the input stream up to a point where the running average of elements is no more than 10:
>>>
import Data.Maybe (fromJust)
>>>
let avg = Scanr.teeWith (/) Scanr.sum (fmap fromIntegral Scanr.length)
>>>
s = Stream.enumerateFromTo 1.0 100.0
>>>
:{
Stream.fold Fold.toList $ fmap fst $ Stream.takeWhile (\(_,x) -> x <= 10) $ Stream.scanr (Scanr.tee Scanr.identity avg) s :} [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0]
dropWhile :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m a Source #
Drop elements in the stream as long as the predicate succeeds and then take the rest of the stream.
drop :: forall (m :: Type -> Type) a. Monad m => Int -> Stream m a -> Stream m a Source #
Discard first n
elements from the stream and take the rest.
reverse :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a Source #
Returns the elements of the stream in reverse order. The stream must be finite. Note that this necessarily buffers the entire stream in memory.
Definition:
>>>
reverse m = Stream.concatEffect $ Stream.fold Fold.toListRev m >>= return . Stream.fromList
elemIndices :: forall (m :: Type -> Type) a. (Monad m, Eq a) => a -> Stream m a -> Stream m Int Source #
Find all the indices where the value of the element in the stream is equal to the given value.
>>>
elemIndices a = Stream.findIndices (== a)
findIndices :: forall (m :: Type -> Type) a. Monad m => (a -> Bool) -> Stream m a -> Stream m Int Source #
Find all the indices where the element in the stream satisfies the given predicate.
>>>
findIndices p = Stream.postscanlMaybe (Scanl.findIndices p)
deleteBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a Source #
Deletes the first occurrence of the element in the stream that satisfies the given equality predicate.
>>>
input = Stream.fromList [1,3,3,5]
>>>
Stream.fold Fold.toList $ Stream.deleteBy (==) 3 input
[1,3,5]
intersperse :: forall (m :: Type -> Type) a. Monad m => a -> Stream m a -> Stream m a Source #
Insert a pure value between successive elements of a stream. It does nothing if stream has less than two elements.
Definition:
>>>
intersperse x = Stream.intersperseM (return x)
>>>
intersperse x = Stream.unfoldEachSepBy x Unfold.identity
>>>
intersperse x = Stream.unfoldEachSepBySeq x Unfold.identity
>>>
intersperse x = Stream.interleaveSepBy (Stream.repeat x)
Example:
>>>
f x y = Stream.toList $ Stream.intersperse x $ Stream.fromList y
>>>
f ',' "abc"
"a,b,c">>>
f ',' "a"
"a"
insertBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a Source #
insertBy cmp elem stream
inserts elem
before the first element in
stream
that is less than elem
when compared using cmp
.
>>>
insertBy cmp x = Stream.mergeBy cmp (Stream.fromPure x)
>>>
input = Stream.fromList [1,3,5]
>>>
Stream.fold Fold.toList $ Stream.insertBy compare 2 input
[1,2,3,5]
filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a Source #
Same as filter
but with a monadic predicate.
>>>
f p x = p x >>= \r -> return $ if r then Just x else Nothing
>>>
filterM p = Stream.mapMaybeM (f p)
scanlx' :: forall (m :: Type -> Type) x a b. Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b Source #
intersperseM :: Monad m => m a -> Stream m a -> Stream m a Source #
Effectful variant of intersperse
. Insert an effect and its output
between successive elements of a stream. It does nothing if stream has less
than two elements.
Definition:
>>>
intersperseM x = Stream.interleaveSepBy (Stream.repeatM x)
postscan :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b Source #
Deprecated: Please use postscanl instead
scanlMany :: forall (m :: Type -> Type) a b. Monad m => Scanl m a b -> Stream m a -> Stream m b Source #
Like scanl
but restarts scanning afresh when the scanning fold
terminates.
dropWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a Source #
Same as dropWhile
but with a monadic predicate.
scan :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b Source #
Deprecated: Please use scanl instead
scanMany :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m b Source #
Deprecated: Please use scanlMany instead
indexed :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m (Int, a) Source #
>>>
f = Scanl.mkScanl (\(i, _) x -> (i + 1, x)) (-1,undefined)
>>>
indexed = Stream.postscanl f
>>>
indexed = Stream.zipWith (,) (Stream.enumerateFrom 0)
>>>
indexedR n = fmap (\(i, a) -> (n - i, a)) . indexed
Pair each element in a stream with its index, starting from index 0.
>>>
Stream.fold Fold.toList $ Stream.indexed $ Stream.fromList "hello"
[(0,'h'),(1,'e'),(2,'l'),(3,'l'),(4,'o')]
splitOn :: forall (m :: Type -> Type) a b. Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b Source #
Deprecated: Please use splitSepBy_ instead. Note the difference in behavior on splitting empty stream.
uniqBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Bool) -> Stream m a -> Stream m a Source #
Drop repeated elements that are adjacent to each other using the supplied comparison function.
>>>
uniq = Stream.uniqBy (==)
To strip duplicate path separators:
>>>
input = Stream.fromList "//a//b"
>>>
f x y = x == '/' && y == '/'
>>>
Stream.fold Fold.toList $ Stream.uniqBy f input
"/a/b"
Space: O(1)
Pre-release
catRights :: forall (m :: Type -> Type) a b. Monad m => Stream m (Either a b) -> Stream m b Source #
catEithers :: forall (m :: Type -> Type) a. Monad m => Stream m (Either a a) -> Stream m a Source #
Remove the either wrapper and flatten both lefts and as well as rights in the output stream.
>>>
catEithers = fmap (either id id)
Pre-release
postscanl :: forall (m :: Type -> Type) a b. Monad m => Scanl m a b -> Stream m a -> Stream m b Source #
Postscan a stream using the given fold. A postscan omits the initial (default) value of the accumulator and includes the final value.
>>>
Stream.toList $ Stream.postscanl Scanl.latest (Stream.fromList [])
[]
Compare with scan
which includes the initial value as well:
>>>
Stream.toList $ Stream.scanl Scanl.latest (Stream.fromList [])
[Nothing]
The following example extracts the input stream up to a point where the running average of elements is no more than 10:
>>>
import Data.Maybe (fromJust)
>>>
let avg = Scanl.teeWith (/) Scanl.sum (fmap fromIntegral Scanl.length)
>>>
s = Stream.enumerateFromTo 1.0 100.0
>>>
:{
Stream.fold Fold.toList $ fmap (fromJust . fst) $ Stream.takeWhile (\(_,x) -> x <= 10) $ Stream.postscanl (Scanl.tee Scanl.latest avg) s :} [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0]
scanMaybe :: forall (m :: Type -> Type) a b. Monad m => Fold m a (Maybe b) -> Stream m a -> Stream m b Source #
Deprecated: Use postscanlMaybe instead
postscanlMaybe :: forall (m :: Type -> Type) a b. Monad m => Scanl m a (Maybe b) -> Stream m a -> Stream m b Source #
Use a filtering scan on a stream.
>>>
postscanlMaybe f = Stream.catMaybes . Stream.postscanl f
tap :: forall (m :: Type -> Type) a b. Monad m => Fold m a b -> Stream m a -> Stream m a Source #
Tap the data flowing through a stream into a Fold
. For example, you may
add a tap to log the contents flowing through the stream. The fold is used
only for effects, its result is discarded.
Fold m a b | -----stream m a ---------------stream m a-----
>>>
s = Stream.enumerateFromTo 1 2
>>>
Stream.fold Fold.drain $ Stream.tap (Fold.drainMapM print) s
1 2
Compare with trace
.
delay :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m a Source #
Introduce a delay of specified seconds between elements of the stream.
Definition:
>>>
sleep n = liftIO $ threadDelay $ round $ n * 1000000
>>>
delay = Stream.intersperseM_ . sleep
Example:
>>>
input = Stream.enumerateFromTo 1 3
>>>
Stream.fold (Fold.drainMapM print) $ Stream.delay 1 input
1 2 3
intersperseM_ :: Monad m => m b -> Stream m a -> Stream m a Source #
Perform a side effect between two successive elements of a stream. It does nothing if the stream has less than two elements.
>>>
f x y = Stream.fold Fold.drain $ Stream.trace putChar $ Stream.intersperseM_ x $ Stream.fromList y
>>>
f (putChar '.') "abc"
a.b.c>>>
f (putChar '.') "a"
a
Pre-release
mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b Source #
Like mapMaybe
but maps a monadic function.
Equivalent to:
>>>
mapMaybeM f = Stream.catMaybes . Stream.mapM f
>>>
mapM f = Stream.mapMaybeM (\x -> Just <$> f x)
splitSepBy_ :: forall (m :: Type -> Type) a b. Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b Source #
Split on an infixed separator element, dropping the separator. The
supplied Fold
is applied on the split segments. Splits the stream on
separator elements determined by the supplied predicate, separator is
considered as infixed between two segments:
Definition:
Usage:
>>>
splitOn p xs = Stream.fold Fold.toList $ Stream.splitSepBy_ p Fold.toList (Stream.fromList xs)
>>>
splitOn (== '.') "a.b"
["a","b"]
Splitting an empty stream results in an empty stream i.e. zero splits:
>>>
splitOn (== '.') ""
[]
If the stream does not contain the separator then it results in a single split:
>>>
splitOn (== '.') "abc"
["abc"]
If one or both sides of the separator are missing then the empty segment on that side is folded to the default output of the fold:
>>>
splitOn (== '.') "."
["",""]
>>>
splitOn (== '.') ".a"
["","a"]
>>>
splitOn (== '.') "a."
["a",""]
>>>
splitOn (== '.') "a..b"
["a","","b"]
splitSepBy_
is an inverse of unfoldEachSepBy
:
Stream.unfoldEachSepBy '.' Unfold.fromList . Stream.splitSepBy_ (== '.') Fold.toList === id
Assuming the input stream does not contain the separator:
Stream.splitSepBy_ (== '.') Fold.toList . Stream.unfoldEachSepBy '.' Unfold.fromList === id
rollingMap :: forall (m :: Type -> Type) a b. Monad m => (Maybe a -> a -> b) -> Stream m a -> Stream m b Source #
Apply a function on every two successive elements of a stream. The first
argument of the map function is the previous element and the second argument
is the current element. When the current element is the first element, the
previous element is Nothing
.
Pre-release
rollingMapM :: Monad m => (Maybe a -> a -> m b) -> Stream m a -> Stream m b Source #
Like rollingMap
but with an effectful map function.
Pre-release
uniq :: forall a (m :: Type -> Type). (Eq a, Monad m) => Stream m a -> Stream m a Source #
Drop repeated elements that are adjacent to each other.
>>>
uniq = Stream.uniqBy (==)
repeated :: forall (m :: Type -> Type) a. Stream m a -> Stream m a Source #
Emit only repeated elements, once.
Unimplemented
prune :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a Source #
Strip all leading and trailing occurrences of an element passing a predicate and make all other consecutive occurrences uniq.
> prune p = Stream.dropWhileAround p $ Stream.uniqBy (x y -> p x && p y)
> Stream.prune isSpace (Stream.fromList " hello world! ") "hello world!"
Space: O(1)
Unimplemented
pipe :: forall (m :: Type -> Type) a b. Monad m => Pipe m a b -> Stream m a -> Stream m b Source #
Use a Pipe
to transform a stream.
intersperseEndByM :: Monad m => m a -> Stream m a -> Stream m a Source #
Insert an effect and its output after every element of a stream.
Definition:
>>>
intersperseEndByM x = Stream.interleaveEndBy (Stream.repeatM x)
Usage:
>>>
f x y = Stream.toList $ Stream.intersperseEndByM (pure x) $ Stream.fromList y
>>>
f ',' "abc"
"a,b,c,">>>
f ',' "a"
"a,"
Pre-release
tapOffsetEvery :: forall (m :: Type -> Type) a b. Monad m => Int -> Int -> Fold m a b -> Stream m a -> Stream m a Source #
trace_ :: Monad m => m b -> Stream m a -> Stream m a Source #
Perform a side effect before yielding each element of the stream and discard the results.
>>>
s = Stream.enumerateFromTo 1 2
>>>
Stream.fold Fold.drain $ Stream.trace_ (print "got here") s
"got here" "got here"
Same as intersperseMPrefix_
but always serial.
See also: trace
Pre-release
foldrS :: forall (m :: Type -> Type) a b. Monad m => (a -> Stream m b -> Stream m b) -> Stream m b -> Stream m a -> Stream m b Source #
foldlS :: forall (m :: Type -> Type) b a. Monad m => (Stream m b -> a -> Stream m b) -> Stream m b -> Stream m a -> Stream m b Source #
scanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b Source #
Like scanl'
but with a monadic step function and a monadic seed.
scanlMAfter' :: Monad m => (b -> a -> m b) -> m b -> (b -> m b) -> Stream m a -> Stream m b Source #
scanlMAfter' accumulate initial done stream
is like scanlM'
except
that it provides an additional done
function to be applied on the
accumulator when the stream stops. The result of done
is also emitted in
the stream.
This function can be used to allocate a resource in the beginning of the scan and release it when the stream ends or to flush the internal state of the scan at the end.
Pre-release
scanlBy :: forall (m :: Type -> Type) b a. Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b Source #
scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a Source #
Like scanl1'
but with a monadic step function.
scanl1' :: forall (m :: Type -> Type) a. Monad m => (a -> a -> a) -> Stream m a -> Stream m a Source #
Like scanl'
but for a non-empty stream. The first element of the stream
is used as the initial value of the accumulator. Does nothing if the stream
is empty.
>>>
Stream.toList $ Stream.scanl1' (+) $ Stream.fromList [1,2,3,4]
[1,3,6,10]
prescanl' :: forall (m :: Type -> Type) b a. Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b Source #
postscanlBy :: forall (m :: Type -> Type) a b. Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a Source #
postscanl' :: forall (m :: Type -> Type) a b. Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a Source #
postscanlMAfter' :: Monad m => (b -> a -> m b) -> m b -> (b -> m b) -> Stream m a -> Stream m b Source #
postscanlx' :: forall (m :: Type -> Type) x a b. Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b Source #
postscanlMx' :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b Source #
sampleFromThen :: forall (m :: Type -> Type) a. Monad m => Int -> Int -> Stream m a -> Stream m a Source #
sampleFromThen offset stride
takes the element at offset
index and
then every element at strides of stride
.
>>>
Stream.fold Fold.toList $ Stream.sampleFromThen 2 3 $ Stream.enumerateFromTo 0 10
[2,5,8]
initNonEmpty :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a Source #
init for non-empty streams, fails for empty stream case.
tailNonEmpty :: forall (m :: Type -> Type) a. Monad m => Stream m a -> Stream m a Source #
tail for non-empty streams, fails for empty stream case.
See also tail
for a non-partial version of this function..
takeWhileLast :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a Source #
Take all consecutive elements at the end of the stream for which the predicate is true.
O(n) space, where n is the number elements taken.
Unimplemented
takeWhileAround :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a Source #
Like takeWhile
and takeWhileLast
combined.
O(n) space, where n is the number elements taken from the end.
Unimplemented
dropLast :: forall (m :: Type -> Type) a. Int -> Stream m a -> Stream m a Source #
Drop n
elements at the end of the stream.
O(n) space, where n is the number elements dropped.
Unimplemented
dropWhileLast :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a Source #
Drop all consecutive elements at the end of the stream for which the predicate is true.
O(n) space, where n is the number elements dropped.
Unimplemented
dropWhileAround :: forall a (m :: Type -> Type). (a -> Bool) -> Stream m a -> Stream m a Source #
Like dropWhile
and dropWhileLast
combined.
O(n) space, where n is the number elements dropped from the end.
Unimplemented
intersperseEveryM :: Int -> m a -> Stream m a -> Stream m a Source #
Intersperse a monadic action into the input stream after every n
elements.
Definition:
> intersperseEveryM n x = Stream.interleaveEverySepBy n (Stream.repeatM x)
Idioms:
>>>
intersperseM = Stream.intersperseEveryM 1
>>>
intersperse x = Stream.intersperseEveryM 1 (return x)
Usage:
> input = Stream.fromList "hello" > Stream.toList $ Stream.intersperseEveryM 2 (return ',') input
"he,ll,o"
Unimplemented
intersperseEndByEveryM :: Monad m => Int -> m a -> Stream m a -> Stream m a Source #
Like intersperseEndByM
but intersperses an effectful action into the
input stream after every n
elements and also after the last element.
Example:
>>>
input = Stream.fromList "hello"
>>>
Stream.toList $ Stream.intersperseEndByEveryM 2 (return ',') input
"he,ll,o,">>>
f n x y = Stream.toList $ Stream.intersperseEndByEveryM n (pure x) $ Stream.fromList y
>>>
f 2 ',' "abcdef"
"ab,cd,ef,">>>
f 2 ',' "abcdefg"
"ab,cd,ef,g,">>>
f 2 ',' "a"
"a,"
Pre-release
intersperseEndByM_ :: Monad m => m b -> Stream m a -> Stream m a Source #
Insert an effect after every element of a stream.
Example:
>>>
f x y = Stream.fold Fold.drain $ Stream.trace putChar $ Stream.intersperseEndByM_ x $ Stream.fromList y
>>>
f (putChar '.') "abc"
a.b.c.>>>
f (putChar '.') "a"
a.
Pre-release
intersperseBeginByM_ :: Monad m => m b -> Stream m a -> Stream m a Source #
Insert a side effect before every element of a stream.
Definition:
>>>
intersperseBeginByM_ = Stream.trace_
>>>
intersperseBeginByM_ m = Stream.mapM (\x -> void m >> return x)
Usage:
>>>
f x y = Stream.fold Fold.drain $ Stream.trace putChar $ Stream.intersperseBeginByM_ x $ Stream.fromList y
>>>
f (putChar '.') "abc"
.a.b.c
Same as trace_
.
Pre-release
delayPre :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m a Source #
Introduce a delay of specified seconds before consuming an element of a stream.
Definition:
>>>
sleep n = liftIO $ threadDelay $ round $ n * 1000000
>>>
delayPre = Stream.intersperseBeginByM_ . sleep
Example:
>>>
input = Stream.enumerateFromTo 1 3
>>>
Stream.fold (Fold.drainMapM print) $ Stream.delayPre 1 input
1 2 3
Pre-release
delayPost :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m a Source #
Introduce a delay of specified seconds after consuming an element of a stream.
Definition:
>>>
sleep n = liftIO $ threadDelay $ round $ n * 1000000
>>>
delayPost = Stream.intersperseEndByM_ . sleep
Example:
>>>
input = Stream.enumerateFromTo 1 3
>>>
Stream.fold (Fold.drainMapM print) $ Stream.delayPost 1 input
1 2 3
Pre-release
reverseUnbox :: forall (m :: Type -> Type) a. (MonadIO m, Unbox a) => Stream m a -> Stream m a Source #
reassembleBy :: forall (m :: Type -> Type) a b. Fold m a b -> (a -> a -> Int) -> Stream m a -> Stream m b Source #
Buffer until the next element in sequence arrives. The function argument determines the difference in sequence numbers. This could be useful in implementing sequenced streams, for example, TCP reassembly.
Unimplemented
indexedR :: forall (m :: Type -> Type) a. Monad m => Int -> Stream m a -> Stream m (Int, a) Source #
>>>
f n = Scanl.mkScanl (\(i, _) x -> (i - 1, x)) (n + 1,undefined)
>>>
indexedR n = Stream.postscanl (f n)
>>>
s n = Stream.enumerateFromThen n (n - 1)
>>>
indexedR n = Stream.zipWith (,) (s n)
Pair each element in a stream with its index, starting from the
given index n
and counting down.
>>>
Stream.fold Fold.toList $ Stream.indexedR 10 $ Stream.fromList "hello"
[(10,'h'),(9,'e'),(8,'l'),(7,'l'),(6,'o')]
timestampWith :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m (AbsTime, a) Source #
Pair each element in a stream with an absolute timestamp, using a clock of specified granularity. The timestamp is generated just before the element is consumed.
>>>
Stream.fold Fold.toList $ Stream.timestampWith 0.01 $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
[(AbsTime (TimeSpec {sec = ..., nsec = ...}),1),(AbsTime (TimeSpec {sec = ..., nsec = ...}),2),(AbsTime (TimeSpec {sec = ..., nsec = ...}),3)]
Pre-release
timestamped :: forall (m :: Type -> Type) a. MonadIO m => Stream m a -> Stream m (AbsTime, a) Source #
timeIndexWith :: forall (m :: Type -> Type) a. MonadIO m => Double -> Stream m a -> Stream m (RelTime64, a) Source #
Pair each element in a stream with relative times starting from 0, using a clock with the specified granularity. The time is measured just before the element is consumed.
>>>
Stream.fold Fold.toList $ Stream.timeIndexWith 0.01 $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
[(RelTime64 (NanoSecond64 ...),1),(RelTime64 (NanoSecond64 ...),2),(RelTime64 (NanoSecond64 ...),3)]
Pre-release
timeIndexed :: forall (m :: Type -> Type) a. MonadIO m => Stream m a -> Stream m (RelTime64, a) Source #
Pair each element in a stream with relative times starting from 0, using a 10 ms granularity clock. The time is measured just before the element is consumed.
>>>
Stream.fold Fold.toList $ Stream.timeIndexed $ Stream.delay 1 $ Stream.enumerateFromTo 1 3
[(RelTime64 (NanoSecond64 ...),1),(RelTime64 (NanoSecond64 ...),2),(RelTime64 (NanoSecond64 ...),3)]
Pre-release
rollingMap2 :: forall (m :: Type -> Type) a b. Monad m => (a -> a -> b) -> Stream m a -> Stream m b Source #
Like rollingMap
but requires at least two elements in the stream,
returns an empty stream otherwise.
This is the stream equivalent of the list idiom zipWith f xs (tail xs)
.
Pre-release
intersperseMSuffix :: Monad m => m a -> Stream m a -> Stream m a Source #
Deprecated: Please use intersperseEndByM instead.
Insert an effect and its output after every element of a stream.
Definition:
>>>
intersperseEndByM x = Stream.interleaveEndBy (Stream.repeatM x)
Usage:
>>>
f x y = Stream.toList $ Stream.intersperseEndByM (pure x) $ Stream.fromList y
>>>
f ',' "abc"
"a,b,c,">>>
f ',' "a"
"a,"
Pre-release
intersperseMSuffixWith :: Monad m => Int -> m a -> Stream m a -> Stream m a Source #
Deprecated: Please use intersperseEndByEveryM instead.
Like intersperseEndByM
but intersperses an effectful action into the
input stream after every n
elements and also after the last element.
Example:
>>>
input = Stream.fromList "hello"
>>>
Stream.toList $ Stream.intersperseEndByEveryM 2 (return ',') input
"he,ll,o,">>>
f n x y = Stream.toList $ Stream.intersperseEndByEveryM n (pure x) $ Stream.fromList y
>>>
f 2 ',' "abcdef"
"ab,cd,ef,">>>
f 2 ',' "abcdefg"
"ab,cd,ef,g,">>>
f 2 ',' "a"
"a,"
Pre-release
intersperseMSuffix_ :: Monad m => m b -> Stream m a -> Stream m a Source #
Deprecated: Please use intersperseEndByM_ instead.
Insert an effect after every element of a stream.
Example:
>>>
f x y = Stream.fold Fold.drain $ Stream.trace putChar $ Stream.intersperseEndByM_ x $ Stream.fromList y
>>>
f (putChar '.') "abc"
a.b.c.>>>
f (putChar '.') "a"
a.
Pre-release
intersperseMPrefix_ :: Monad m => m b -> Stream m a -> Stream m a Source #
Deprecated: Please use intersperseBeginByM_ instead.
Insert a side effect before every element of a stream.
Definition:
>>>
intersperseBeginByM_ = Stream.trace_
>>>
intersperseBeginByM_ m = Stream.mapM (\x -> void m >> return x)
Usage:
>>>
f x y = Stream.fold Fold.drain $ Stream.trace putChar $ Stream.intersperseBeginByM_ x $ Stream.fromList y
>>>
f (putChar '.') "abc"
.a.b.c
Same as trace_
.
Pre-release
strideFromThen :: forall (m :: Type -> Type) a. Monad m => Int -> Int -> Stream m a -> Stream m a Source #
Deprecated: Please use sampleFromThen instead.
sampleFromThen offset stride
takes the element at offset
index and
then every element at strides of stride
.
>>>
Stream.fold Fold.toList $ Stream.sampleFromThen 2 3 $ Stream.enumerateFromTo 0 10
[2,5,8]
unionBy :: forall (m :: Type -> Type) a. MonadIO m => (a -> a -> Bool) -> Stream m a -> Stream m a -> Stream m a Source #
Returns the first stream appended with those unique elements from the
second stream that are not already present in the first stream. Note that
this is not a commutative operation unlike a set union, argument order
matters. The behavior is similar to unionBy
.
Equivalent to the following except that s2
is evaluated only once:
>>>
unionBy eq s1 s2 = s1 `Stream.append` Stream.deleteFirstsBy eq s1 (Stream.ordNub s2)
Example:
>>>
f s1 s2 = Stream.fold Fold.toList $ Stream.unionBy (==) (Stream.fromList s1) (Stream.fromList s2)
>>>
f [1,2,2,4] [1,1,2,3,3]
[1,2,2,4,3]
First stream can be infinite, but second stream must be finite. Note that if
the first stream is infinite the union means just the first stream. Thus
union is useful only when both streams are finite. See sortedUnionBy
where
union can work on infinite streams if they are sorted.
Space: O(n)
Time: O(m x n)
Pre-release
intersectBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Bool) -> Stream m a -> Stream m a -> Stream m a Source #
intersectBy
returns a subsequence of the first stream which intersects
with the second stream. Note that this is not a commutative operation unlike
a set intersection, because of duplicate elements in the stream the order of
the streams matters. This is similar to intersectBy
. Note that
intersectBy is a special case of innerJoin
.
>>>
f s1 s2 = Stream.fold Fold.toList $ Stream.intersectBy (==) (Stream.fromList s1) (Stream.fromList s2)
>>>
f [1,3,4,4,5] [2,3,4,5,5]
[3,4,4,5]
First stream can be infinite, the second stream must be finite and must be capable of multiple evaluations.
Space: O(n) where n
is the number of elements in the second stream.
Time: O(m x n) where m
is the number of elements in the first stream and
n
is the number of elements in the second stream.
Pre-release
deleteFirstsBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Bool) -> Stream m a -> Stream m a -> Stream m a Source #
Returns a subsequence of the first stream, deleting first occurrences of
those elements that are present in the second stream. Note that this is not
a commutative operation. This is similar to the deleteFirstsBy
.
>>>
f xs ys = Stream.fold Fold.toList $ Stream.deleteFirstsBy (==) (Stream.fromList xs) (Stream.fromList ys)
>>>
f [1,2,2,3,3,5] [1,2,2,3,4]
[3,5]
The following holds:
deleteFirstsBy (==) (Stream.ordNub s2 `append` s1) s2 === s1 deleteFirstsBy (==) (Stream.ordNub s2 `interleave` s1) s2 === s1
First stream can be infinite, second stream must be finite.
Space: O(m) where m
is the number of elements in the first stream.
Time: O(m x n) where m
is the number of elements in the first stream and
n
is the number of elements in the second stream.
Pre-release
innerJoin :: forall (m :: Type -> Type) a b. Monad m => (a -> b -> Bool) -> Stream m a -> Stream m b -> Stream m (a, b) Source #
Like cross
but emits only those tuples where a == b
using the supplied
equality predicate. This is essentially a cross intersection
of two
streams.
Definition:
>>>
innerJoin eq s1 s2 = Stream.filter (\(a, b) -> a `eq` b) $ Stream.cross s1 s2
The second (inner) stream must be finite. Moreover, it must be either pure
or capable of multiple evaluations. If not then the caller should cache it
in an Array
, if the type does not have an Unbox
instance then
use the Generic Array
. Convert the array to stream
before calling this function. Caching may also improve performance if the
stream is expensive to evaluate.
If you care about performance this function should be your last choice among
all inner joins. innerJoin
is a much faster
fused alternative. innerSortedJoin
is a faster alternative when streams
are sorted. innerOrdJoin
is an order of magnitude faster alternative when
the type has an Ord
instance.
Note: Conceptually, this is a commutative operation. Result includes all the elements from the left and the right stream. The order of streams can be changed without affecting results, except for the ordering within the tuple.
Time: O(m x n)
Pre-release
sortedIntersectBy :: forall (m :: Type -> Type) a. Monad m => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a Source #
Like intersectBy
but assumes that the input streams are sorted in
ascending order. To use it on streams sorted in descending order pass an
inverted comparison function returning GT for less than and LT for greater
than.
Both streams can be infinite.
Space: O(1)
Time: O(m+n)
Pre-release
sortedDeleteFirstsBy :: forall a (m :: Type -> Type). (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a Source #
A more efficient deleteFirstsBy
for streams sorted in ascending order.
Both streams can be infinite.
Space: O(1)
Unimplemented
sortedUnionBy :: forall a (m :: Type -> Type). (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a Source #
A more efficient unionBy
for sorted streams.
Note that the behavior is different from unionBy
. In unionBy
we append
the unique elements from second stream only after exhausting the first one
whereas in sorted streams we can determine unique elements early even when
we are going through the first stream. Thus the result is an interleaving of
the two streams, merging those elements from the second stream that are not
present in the first.
Space: O(1)
Both streams can be infinite.
Unimplemented
innerSortedJoin :: forall a b (m :: Type -> Type). (a -> b -> Ordering) -> Stream m a -> Stream m b -> Stream m (a, b) Source #
leftSortedJoin :: forall a b (m :: Type -> Type). (a -> b -> Ordering) -> Stream m a -> Stream m b -> Stream m (a, Maybe b) Source #
A more efficient leftJoin
for sorted streams.
Space: O(1)
Time: O(m + n)
Unimplemented
outerSortedJoin :: forall a b (m :: Type -> Type). (a -> b -> Ordering) -> Stream m a -> Stream m b -> Stream m (Maybe a, Maybe b) Source #
A more efficient outerJoin
for sorted streams.
Space: O(1)
Time: O(m + n)
Unimplemented
ordNub :: forall (m :: Type -> Type) a. (Monad m, Ord a) => Stream m a -> Stream m a Source #
nub
specialized to Ord
types for better performance. Returns a
subsequence of the stream removing any duplicate elements.
The memory used is proportional to the number of unique elements in the
stream. One way to limit the memory is to use take
on the resulting
stream to limit the unique elements in the stream.
leftJoin :: forall (m :: Type -> Type) a b. Monad m => (a -> b -> Bool) -> Stream m a -> Stream m b -> Stream m (a, Maybe b) Source #
Like innerJoin
but emits (a, Just b)
whenever a and b are equal, for
those a
's that are not equal to any b
emits (a, Nothing)
.
This is a generalization of innerJoin
to include all elements from the
left stream and not just those which have an equal in the right stream. This
is not a commutative operation, the order of the stream arguments matters.
All the caveats mentioned in innerJoin
apply here as well. Right join is
not provided because it is just a flipped left join:
>>>
rightJoin eq = flip (Stream.leftJoin eq)
Space: O(n) assuming the second stream is cached in memory.
Time: O(m x n)
Unimplemented
outerJoin :: forall (m :: Type -> Type) a b. MonadIO m => (a -> b -> Bool) -> Stream m a -> Stream m b -> Stream m (Maybe a, Maybe b) Source #
Like leftJoin
but emits a (Just a, Just b)
. Like leftJoin
, for those
a
's that are not equal to any b
emit (Just a, Nothing)
, but
additionally, for those b
's that are not equal to any a
emit (Nothing,
Just b)
.
This is a generalization of left join to include all the elements from the right stream as well, in other words it is a combination of left and right joins. This is a commutative operation. The order of stream arguments can be changed without affecting results, except for the ordering of elements in the resulting tuple.
For space efficiency use the smaller stream as the second stream.
Space: O(n)
Time: O(m x n)
Pre-release
innerOrdJoin :: forall (m :: Type -> Type) k a b. (Monad m, Ord k) => Stream m (k, a) -> Stream m (k, b) -> Stream m (k, a, b) Source #
innerJoin
specialized to Ord
types for better performance.
If the input streams have duplicate keys, the behavior is undefined.
For space efficiency use the smaller stream as the second stream.
Space: O(n)
Time: O(m + n)
Pre-release