@@ -35,6 +35,8 @@ module Streamly.Internal.Data.Stream.Zip
3535 )
3636where
3737
38+#include "inline.hs"
39+
3840import Control.Applicative (liftA2)
3941import Control.DeepSeq (NFData(..))
4042#if MIN_VERSION_deepseq(1,4,3)
@@ -56,18 +58,13 @@ import Streamly.Internal.Data.Stream.StreamK (IsStream(..), Stream)
5658import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
5759import Streamly.Internal.Data.SVar (MonadAsync)
5860
61+import Streamly.Internal.Data.Stream.Serial (SerialT)
62+
5963import qualified Streamly.Internal.Data.Stream.Parallel as Par
6064import qualified Streamly.Internal.Data.Stream.Prelude as P
61− (cmpBy, eqBy, foldl', foldr, fromList, toList, fromStreamS, toStreamS)
62−import qualified Streamly.Internal.Data.Stream.StreamK as K (repeat)
63−import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
64−import qualified Streamly.Internal.Data.Stream.StreamD as D (zipWithM)
65−import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
66−#ifdef USE_STREAMK_ONLY
67−import qualified Streamly.Internal.Data.Stream.StreamK as S (zipWith, zipWithM)
68−#else
69−import qualified Streamly.Internal.Data.Stream.StreamD as S (zipWith, zipWithM)
70−#endif
65+ (cmpBy, eqBy, foldl', foldr, fromList, toList)
66+import qualified Streamly.Internal.Data.Stream.StreamK as K
67+import qualified Streamly.Internal.Data.Stream.StreamD as D
7168
7269import Prelude hiding (map, repeat, zipWith, errorWithoutStackTrace)
7370
@@ -85,11 +82,21 @@ import Prelude hiding (map, repeat, zipWith, errorWithoutStackTrace)
8582-- | Like 'zipWith' but using a monadic zipping function.
8683--
8784-- @since 0.4.0
88−{-# INLINABLE zipWithM #-}
89−zipWithM :: (IsStream t, Monad m) => (a -> b -> m c) -> t m a -> t m b -> t m c
90−zipWithM f m1 m2 = P.fromStreamS $ S.zipWithM f (P.toStreamS m1) (P.toStreamS m2)
91−
92−-- | Zip two streams serially using a pure zipping function.
85+{-# INLINE_EARLY zipWithM #-}
86+zipWithM ::
87+ (IsStream t, MonadAsync m) => (a -> b -> m c) -> t m a -> t m b -> t m c
88+zipWithM f m1 m2 =
89+ K.fromStream $ K.zipWithM f (K.toStream m1) (K.toStream m2)
90+
91+{-# RULES "zipWithM serial" zipWithM = zipWithMSerial #-}
92+{-# INLINE zipWithMSerial #-}
93+zipWithMSerial ::
94+ Monad m => (a -> b -> m c) -> SerialT m a -> SerialT m b -> SerialT m c
95+zipWithMSerial f m1 m2 =
96+ D.fromStreamD $ D.zipWithM f (D.toStreamD m1) (D.toStreamD m2)
97+
98+-- | Zip two streams serially using a pure zipping function. The zipping
99+-- function is applied concurrently for concurrent streams.
93100--
94101-- @
95102-- > S.toList $ S.zipWith (+) (S.fromList [1,2,3]) (S.fromList [4,5,6])
@@ -97,9 +104,17 @@ zipWithM f m1 m2 = P.fromStreamS $ S.zipWithM f (P.toStreamS m1) (P.toStreamS m2
97104-- @
98105--
99106-- @since 0.1.0
100−{-# INLINABLE zipWith #-}
101−zipWith :: (IsStream t, Monad m) => (a -> b -> c) -> t m a -> t m b -> t m c
102−zipWith f m1 m2 = P.fromStreamS $ S.zipWith f (P.toStreamS m1) (P.toStreamS m2)
107+{-# INLINE_EARLY zipWith #-}
108+zipWith ::
109+ (IsStream t, MonadAsync m) => (a -> b -> c) -> t m a -> t m b -> t m c
110+zipWith f m1 m2 = K.fromStream $ K.zipWith f (K.toStream m1) (K.toStream m2)
111+
112+{-# RULES "zipWith serial" zipWith = zipWithSerial #-}
113+{-# INLINE zipWithSerial #-}
114+zipWithSerial ::
115+ Monad m => (a -> b -> c) -> SerialT m a -> SerialT m b -> SerialT m c
116+zipWithSerial f m1 m2 =
117+ D.fromStreamD $ D.zipWith f (D.toStreamD m1) (D.toStreamD m2)
103118
104119------------------------------------------------------------------------------
105120-- Parallel Zipping
@@ -204,7 +219,10 @@ instance Monad m => Functor (ZipSerialM m) where
204219instance Monad m => Applicative (ZipSerialM m) where
205220 pure = ZipSerialM . K.repeat
206221 {-# INLINE (<*>) #-}
207− (<*>) = zipWith id
222+ m1 <*> m2 = fromStream $ toStream $ zipWithSerial id m1_ m2_
223+ where
224+ m1_ = fromStream (toStream m1)
225+ m2_ = fromStream (toStream m2)
208226
209227FOLDABLE_INSTANCE(ZipSerialM)
210228TRAVERSABLE_INSTANCE(ZipSerialM)