on master help sign in
Implement <*> and >> for SerialT via StreamD.
commit0d7dad84e472d832aad7d96c43bbc7b6217f42bb authorPranay Sashank <pranaysashank@gmail.com> dateMon 23 Dec 2019, 15:59 (7 years ago) parent5949f4c
2 files changed+66−20
src/Streamly/Internal/Data/Stream/Serial.hs+9−4 src/Streamly/Internal/Data/Stream/StreamD/Type.hs+57−16
src/Streamly/Internal/Data/Stream/Serial.hs+9−4
@@ -76,7 +76,6 @@ import Streamly.Internal.Data.Stream.StreamK (IsStream(..), adapt, Stream, mkStr
7676import qualified Streamly.Internal.Data.Stream.Prelude as P
7777import qualified Streamly.Internal.Data.Stream.StreamK as K
7878import qualified Streamly.Internal.Data.Stream.StreamD as D
79−import qualified Streamly.Internal.Data.Unfold as UF
8079
8180#include "Instances.hs"
8281#include "inline.hs"
@@ -181,6 +180,8 @@ instance Monad m => Monad (SerialT m) where
181180 return = pure
182181 {-# INLINE (>>=) #-}
183182 (>>=) = K.bindWith K.serial
183+ {-# INLINE (>>) #-}
184+ (>>) = (*>)
184185
185186 -- StreamD based implementation
186187 -- return = SerialT . D.fromStreamD . D.yield
@@ -213,15 +214,19 @@ map f = mapM (return . f)
213214
214215{-# INLINE apSerial #-}
215216apSerial :: Monad m => SerialT m (a -> b) -> SerialT m a -> SerialT m b
216−apSerial (SerialT m1) (SerialT m2) =
217− let f x1 = D.concatMapU (UF.singleton (pure . x1)) (D.toStreamD m2)
218− in D.fromStreamD $ D.concatMap f (D.toStreamD m1)
217+apSerial (SerialT m1) (SerialT m2) = D.fromStreamD $ D.toStreamD m1 <*> D.toStreamD m2
218+
219+{-# INLINE apSequence #-}
220+apSequence :: Monad m => SerialT m a -> SerialT m b -> SerialT m b
221+apSequence (SerialT m1) (SerialT m2) = D.fromStreamD $ D.toStreamD m1 *> D.toStreamD m2
219222
220223instance Monad m => Applicative (SerialT m) where
221224 {-# INLINE pure #-}
222225 pure = SerialT . K.yield
223226 {-# INLINE (<*>) #-}
224227 (<*>) = apSerial
228+ {-# INLINE (*>) #-}
229+ (*>) = apSequence
225230
226231MONAD_COMMON_INSTANCES(SerialT,)
227232LIST_INSTANCES(SerialT)
src/Streamly/Internal/Data/Stream/StreamD/Type.hs+57−16
@@ -90,13 +90,11 @@ import qualified Streamly.Internal.Data.Stream.StreamK as K
9090-- the stream.
9191data Step s a = Yield a s | Skip s | Stop
9292
93−{-
9493instance Functor (Step s) where
9594 {-# INLINE fmap #-}
9695 fmap f (Yield x s) = Yield (f x) s
9796 fmap _ (Skip s) = Skip s
9897 fmap _ Stop = Stop
99−-}
10098
10199-- gst = global state
102100-- | A stream consists of a step function that generates the next step given a
@@ -176,9 +174,12 @@ mapM f (Stream step state) = Stream step' state
176174map :: Monad m => (a -> b) -> Stream m a -> Stream m b
177175map f = mapM (return . f)
178176
179−instance Monad m => Functor (Stream m) where
177+instance Functor m => Functor (Stream m) where
180178 {-# INLINE fmap #-}
181− fmap = map
179+ fmap f (Stream step state) = Stream step' state
180+ where
181+ {-# INLINE_LATE step' #-}
182+ step' gst st = fmap (fmap f) (step (adaptState gst) st)
182183
183184------------------------------------------------------------------------------
184185-- concatMap
@@ -231,23 +232,61 @@ concatMap f = concatMapM (return . f)
231232
232233-- | Create a singleton 'Stream' from a pure value.
233234{-# INLINE_NORMAL yield #-}
234−yield :: Monad m => a -> Stream m a
235−yield x = Stream (\_ s -> return $ step undefined s) True
235+yield :: Applicative m => a -> Stream m a
236+yield x = Stream (\_ s -> pure $ step undefined s) True
236237 where
237238 {-# INLINE_LATE step #-}
238239 step _ True = Yield x False
239240 step _ False = Stop
240241
241−instance Monad m => Applicative (Stream m) where
242+{-# INLINE_NORMAL concatAp #-}
243+concatAp :: Functor f => Stream f (a -> b) -> Stream f a -> Stream f b
244+concatAp (Stream stepa statea) (Stream stepb stateb) = Stream step' (Left statea)
245+ where
246+ {-# INLINE_LATE step' #-}
247+ step' gst (Left st) = fmap
248+ (\r -> case r of
249+ Yield f s -> Skip (Right (f, s, stateb))
250+ Skip s -> Skip (Left s)
251+ Stop -> Stop)
252+ (stepa (adaptState gst) st)
253+ step' gst (Right (f, os, st)) = fmap
254+ (\r -> case r of
255+ Yield a s -> Yield (f a) (Right (f, os, s))
256+ Skip s -> Skip (Right (f,os, s))
257+ Stop -> Skip (Left os))
258+ (stepb (adaptState gst) st)
259+
260+{-# INLINE_NORMAL apSequence #-}
261+apSequence :: Functor f => Stream f a -> Stream f b -> Stream f b
262+apSequence (Stream stepa statea) (Stream stepb stateb) = Stream step (Left statea)
263+ where
264+ {-# INLINE_LATE step #-}
265+ step gst (Left st) =
266+ fmap
267+ (\r ->
268+ case r of
269+ Yield _ s -> Skip (Right (s, stateb))
270+ Skip s -> Skip (Left s)
271+ Stop -> Stop)
272+ (stepa (adaptState gst) st)
273+ step gst (Right (ostate, st)) =
274+ fmap
275+ (\r ->
276+ case r of
277+ Yield b s -> Yield b (Right (ostate, s))
278+ Skip s -> Skip (Right (ostate, s))
279+ Stop -> Skip (Left ostate))
280+ (stepb gst st)
281+
282+instance Applicative f => Applicative (Stream f) where
242283 {-# INLINE pure #-}
243284 pure = yield
244285 {-# INLINE (<*>) #-}
245− m1 <*> m2 =
246− -- XXX concatMapU is faster but it would require us to merge
247− -- Unfold/Types.hs into this file so that we can use UF.singleton here.
248− -- let f x1 = concatMapU (UF.singleton (pure . x1)) m2
249− let f x1 = concatMap (\x2 -> pure (x1 x2)) m2
250− in concatMap f m1
286+ (<*>) = concatAp
287+ {-# INLINE (*>) #-}
288+ (*>) = apSequence
289+
251290
252291-- NOTE: even though concatMap for StreamD is 4x faster compared to StreamK,
253292-- the monad instance does not seem to be significantly faster.
@@ -256,6 +295,8 @@ instance Monad m => Monad (Stream m) where
256295 return = pure
257296 {-# INLINE (>>=) #-}
258297 (>>=) = flip concatMap
298+ {-# INLINE (>>) #-}
299+ (>>) = (*>)
259300
260301instance MonadTrans Stream where
261302 lift = yieldM
@@ -425,12 +466,12 @@ foldl' fstep = foldlM' (\b a -> return (fstep b a))
425466
426467-- | Convert a list of pure values to a 'Stream'
427468{-# INLINE_LATE fromList #-}
428−fromList :: Monad m => [a] -> Stream m a
469+fromList :: Applicative m => [a] -> Stream m a
429470fromList = Stream step
430471 where
431472 {-# INLINE_LATE step #-}
432− step _ (x:xs) = return $ Yield x xs
433− step _ [] = return Stop
473+ step _ (x:xs) = pure $ Yield x xs
474+ step _ [] = pure Stop
434475
435476------------------------------------------------------------------------------
436477-- Comparisons