@@ -1,7 +1,7 @@
1#include "inline.hs"
1#include "inline.hs"
4−-- Module : Streamly.Internal.Data.Stream.StreamD.Flatten
4+-- Module : Streamly.Internal.Data.Stream.StreamD.Combine
5-- Copyright : (c) 2018 Composewell Technologies
5-- Copyright : (c) 2018 Composewell Technologies
6-- (c) Roman Leshchinskiy 2008-2010
6-- (c) Roman Leshchinskiy 2008-2010
7-- (c) The University of Glasgow, 2009
7-- (c) The University of Glasgow, 2009
@@ -10,10 +10,20 @@
10-- Stability : experimental
10-- Stability : experimental
11-- Portability : GHC
11-- Portability : GHC
13−module Streamly.Internal.Data.Stream.StreamD.Flatten
13+module Streamly.Internal.Data.Stream.StreamD.Combine
15 -- ** Flattening nested streams
25 -- ** Flattening nested streams
16− concatMapM
26+ , concatMapM
17 , concatMap
27 , concatMap
18 , ConcatMapUState (..)
28 , ConcatMapUState (..)
19 , concatMapU
29 , concatMapU
@@ -35,6 +45,9 @@ module Streamly.Internal.Data.Stream.StreamD.Flatten
48+#if __GLASGOW_HASKELL__ >= 801
49+import Data.Functor.Identity ( Identity )
38import Fusion.Plugin.Types (Fuse(..))
51import Fusion.Plugin.Types (Fuse(..))
39import Streamly.Internal.Data.Unfold.Types (Unfold(..))
52import Streamly.Internal.Data.Unfold.Types (Unfold(..))
@@ -48,6 +61,117 @@ import Prelude hiding
48import Streamly.Internal.Data.Stream.StreamD.Type
61import Streamly.Internal.Data.Stream.StreamD.Type
49import Streamly.Internal.Data.SVar
62import Streamly.Internal.Data.SVar
64+------------------------------------------------------------------------------
66+------------------------------------------------------------------------------
68+{-# INLINE_NORMAL indexed #-}
69+indexed :: Monad m => Stream m a -> Stream m (Int, a)
70+indexed (Stream step state) = Stream step' (state, 0)
72+ {-# INLINE_LATE step' #-}
73+ step' gst (st, i) = i `seq` do
74+ r <- step (adaptState gst) st
76+ Yield x s -> return $ Yield (i, x) (s, i+1)
77+ Skip s -> return $ Skip (s, i)
80+{-# INLINE_NORMAL indexedR #-}
81+indexedR :: Monad m => Int -> Stream m a -> Stream m (Int, a)
82+indexedR m (Stream step state) = Stream step' (state, m)
84+ {-# INLINE_LATE step' #-}
85+ step' gst (st, i) = i `seq` do
86+ r <- step (adaptState gst) st
88+ Yield x s -> let i' = i - 1
89+ in return $ Yield (i, x) (s, i')
90+ Skip s -> return $ Skip (s, i)
93+{-# INLINE_NORMAL zipWithM #-}
95+ => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
96+zipWithM f (Stream stepa ta) (Stream stepb tb) = Stream step (ta, tb, Nothing)
98+ {-# INLINE_LATE step #-}
99+ step gst (sa, sb, Nothing) = do
100+ r <- stepa (adaptState gst) sa
103+ Yield x sa' -> Skip (sa', sb, Just x)
104+ Skip sa' -> Skip (sa', sb, Nothing)
107+ step gst (sa, sb, Just x) = do
108+ r <- stepb (adaptState gst) sb
112+ return $ Yield z (sa, sb', Nothing)
113+ Skip sb' -> return $ Skip (sa, sb', Just x)
116+#if __GLASGOW_HASKELL__ >= 801
117+{-# RULES "zipWithM xs xs"
118+ forall f xs. zipWithM @Identity f xs xs = mapM (\x -> f x x) xs #-}
121+{-# INLINE zipWith #-}
122+zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
123+zipWith f = zipWithM (\a b -> return (f a b))
125+------------------------------------------------------------------------------
127+------------------------------------------------------------------------------
129+{-# INLINE_NORMAL mergeByM #-}
132+ => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
133+mergeByM cmp (Stream stepa ta) (Stream stepb tb) =
134+ Stream step (Just ta, Just tb, Nothing, Nothing)
136+ {-# INLINE_LATE step #-}
138+ -- one of the values is missing, and the corresponding stream is running
139+ step gst (Just sa, sb, Nothing, b) = do
142+ Yield a sa' -> Skip (Just sa', sb, Just a, b)
143+ Skip sa' -> Skip (Just sa', sb, Nothing, b)
144+ Stop -> Skip (Nothing, sb, Nothing, b)
146+ step gst (sa, Just sb, a, Nothing) = do
149+ Yield b sb' -> Skip (sa, Just sb', a, Just b)
150+ Skip sb' -> Skip (sa, Just sb', a, Nothing)
151+ Stop -> Skip (sa, Nothing, a, Nothing)
153+ -- both the values are available
154+ step _ (sa, sb, Just a, Just b) = do
156+ return $ case res of
157+ GT -> Yield b (sa, sb, Just a, Nothing)
158+ _ -> Yield a (sa, sb, Nothing, Just b)
160+ -- one of the values is missing, corresponding stream is done
161+ step _ (Nothing, sb, Nothing, Just b) =
162+ return $ Yield b (Nothing, sb, Nothing, Nothing)
164+ step _ (sa, Nothing, Just a, Nothing) =
165+ return $ Yield a (sa, Nothing, Nothing, Nothing)
167+ step _ (Nothing, Nothing, Nothing, Nothing) = return Stop
169+{-# INLINE mergeBy #-}
172+ => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
173+mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
51-------------------------------------------------------------------------------
175-------------------------------------------------------------------------------
52-- Stream transformations using Unfolds
176-- Stream transformations using Unfolds
53-------------------------------------------------------------------------------
177-------------------------------------------------------------------------------