on master help sign in
Change signatures of zipWith/zipWithM
8af1c36Harendra Kumar
benchmark/Streamly/Benchmark/Data/Unfold.hs+3−3
@@ -384,7 +384,7 @@ dropWhileMFalse size start =
384{-# INLINE zipWith #-}
384{-# INLINE zipWith #-}
385zipWith :: Monad m => Int -> Int -> m ()
385zipWith :: Monad m => Int -> Int -> m ()
386zipWith size start =
386zipWith size start =
387− drainProductDefault (size + start) (UF.zipWith (+)) (start, start + 1)
387+ drainProductDefault (size + start) (UF.zipWith (+)) start
388
388
389{-# INLINE zipWithM #-}
389{-# INLINE zipWithM #-}
390zipWithM :: Monad m => Int -> Int -> m ()
390zipWithM :: Monad m => Int -> Int -> m ()
@@ -392,12 +392,12 @@ zipWithM size start =
392 drainProductDefault
392 drainProductDefault
393 (size + start)
393 (size + start)
394 (UF.zipWithM (\a b -> return $ a + b))
394 (UF.zipWithM (\a b -> return $ a + b))
395− (start, start + 1)
395+ start
396
396
397{-# INLINE teeZipWith #-}
397{-# INLINE teeZipWith #-}
398teeZipWith :: Monad m => Int -> Int -> m ()
398teeZipWith :: Monad m => Int -> Int -> m ()
399teeZipWith size start =
399teeZipWith size start =
400− drainProductDefault (size + start) (UF.teeZipWith (+)) start
400+ drainProductDefault (size + start) (UF.zipWith (+)) start
401
401
402-------------------------------------------------------------------------------
402-------------------------------------------------------------------------------
403-- Applicative
403-- Applicative
src/Streamly/Data/Unfold.hs−1
@@ -94,7 +94,6 @@ module Streamly.Data.Unfold
94 , dropWhileM
94 , dropWhileM
95
95
96 -- ** Zipping
96 -- ** Zipping
97− , zipWithM
98 , zipWith
97 , zipWith
99
98
100 -- ** Cross Product
99 -- ** Cross Product
src/Streamly/Internal/Data/Unfold.hs−19
@@ -159,7 +159,6 @@ module Streamly.Internal.Data.Unfold
159 -- ** Zipping
159 -- ** Zipping
160 , zipWithM
160 , zipWithM
161 , zipWith
161 , zipWith
162− , teeZipWith
163
162
164 -- ** Cross product
163 -- ** Cross product
165 , crossWithM
164 , crossWithM
@@ -881,24 +880,6 @@ fromProducer = Unfold step (return . FromSVarRead)
881
880
882 step (FromSVarInit _) = undefined
881 step (FromSVarInit _) = undefined
883
882
884−-------------------------------------------------------------------------------
885−-- Zipping
886−-------------------------------------------------------------------------------
887−
888−-- | Distribute the input to two unfolds and then zip the outputs to a single
889−-- stream.
890−--
891−-- @
892−-- S.mapM_ print $ S.unfoldMany (UF.teeZipWith (,) UF.identity (UF.singleton sqrt)) $ S.fromList [1..10]
893−-- @
894−--
895−-- /Pre-release/
896−--
897−{-# INLINE_NORMAL teeZipWith #-}
898−teeZipWith :: Monad m
899− => (a -> b -> c) -> Unfold m x a -> Unfold m x b -> Unfold m x c
900−teeZipWith f unf1 unf2 = lmap (\x -> (x,x)) $ zipWith f unf1 unf2
901−
902------------------------------------------------------------------------------
883------------------------------------------------------------------------------
903-- Exceptions
884-- Exceptions
904------------------------------------------------------------------------------
885------------------------------------------------------------------------------
src/Streamly/Internal/Data/Unfold/Type.hs+28−21
@@ -54,8 +54,8 @@ import Prelude hiding (const, map, concatMap, zipWith)
54-- $setup
54-- $setup
55-- >>> :m
55-- >>> :m
56-- >>> import qualified Streamly.Prelude as Stream
56-- >>> import qualified Streamly.Prelude as Stream
57−-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
57+-- >>> import qualified Streamly.Data.Fold as Fold
58−-- >>> import qualified Streamly.Internal.Data.Unfold as Unfold
58+-- >>> import qualified Streamly.Data.Unfold as Unfold
59
59
60------------------------------------------------------------------------------
60------------------------------------------------------------------------------
61-- Monadic Unfolds
61-- Monadic Unfolds
@@ -125,7 +125,7 @@ yieldM m = Unfold step inject
125
125
126-- | Discards the unfold input and always returns the argument of 'yield'.
126-- | Discards the unfold input and always returns the argument of 'yield'.
127yield :: Applicative m => b -> Unfold m a b
127yield :: Applicative m => b -> Unfold m a b
128−yield = yieldM . pure
128+yield = yieldM Prelude.. pure
129
129
130-- | Outer product discarding the first element.
130-- | Outer product discarding the first element.
131--
131--
@@ -218,7 +218,7 @@ apply u1 u2 = fmap (\(a, b) -> a b) (cross u1 u2)
218--
218--
219instance Monad m => Applicative (Unfold m a) where
219instance Monad m => Applicative (Unfold m a) where
220 {-# INLINE pure #-}
220 {-# INLINE pure #-}
221− pure = const Prelude.. return
221+ pure = yield
222
222
223 {-# INLINE (<*>) #-}
223 {-# INLINE (<*>) #-}
224 (<*>) = apply
224 (<*>) = apply
@@ -314,8 +314,6 @@ instance Monad m => Monad (Unfold m a) where
314-- Category
314-- Category
315-------------------------------------------------------------------------------
315-------------------------------------------------------------------------------
316
316
317−-- XXX change it to yieldM or change yieldM in Prelude to singletonM
318−--
319-- | Lift a monadic function into an unfold generating a singleton stream.
317-- | Lift a monadic function into an unfold generating a singleton stream.
320--
318--
321{-# INLINE singletonM #-}
319{-# INLINE singletonM #-}
@@ -397,20 +395,25 @@ instance Monad m => Category (Unfold m) where
397-}
395-}
398
396
399-------------------------------------------------------------------------------
397-------------------------------------------------------------------------------
400−-- Arrow
398+-- Zipping
401-------------------------------------------------------------------------------
399-------------------------------------------------------------------------------
402
400
401+-- | Distribute the input to two unfolds and then zip the outputs to a single
402+-- stream using a monadic zip function.
403+--
403−-- | Stops as soon as any of the unfolds stops.
404+-- Stops as soon as any of the unfolds stops.
405+--
406+-- /Pre-release/
404{-# INLINE_NORMAL zipWithM #-}
407{-# INLINE_NORMAL zipWithM #-}
405zipWithM :: Monad m
408zipWithM :: Monad m
406− => (a -> b -> m c) -> Unfold m x a -> Unfold m y b -> Unfold m (x, y) c
409+ => (b -> c -> m d) -> Unfold m a b -> Unfold m a c -> Unfold m a d
407zipWithM f (Unfold step1 inject1) (Unfold step2 inject2) = Unfold step inject
410zipWithM f (Unfold step1 inject1) (Unfold step2 inject2) = Unfold step inject
408
411
409 where
412 where
410
413
411− inject (x, y) = do
414+ inject x = do
412 s1 <- inject1 x
415 s1 <- inject1 x
413− s2 <- inject2 y
416+ s2 <- inject2 x
414 return (s1, s2, Nothing)
417 return (s1, s2, Nothing)
415
418
416 {-# INLINE_LATE step #-}
419 {-# INLINE_LATE step #-}
@@ -431,23 +434,27 @@ zipWithM f (Unfold step1 inject1) (Unfold step2 inject2) = Unfold step inject
431 Skip s -> return $ Skip (s1, s, Just x)
434 Skip s -> return $ Skip (s1, s, Just x)
432 Stop -> return Stop
435 Stop -> return Stop
433
436
434−-- | Divide the input into two unfolds and then zip the outputs to a single
437+-- | Like 'zipWithM' but with a pure zip function.
435−-- stream.
436--
438--
437−-- @
439+-- >>> square = fmap (\x -> x * x) Unfold.fromList
438−-- S.mapM_ print
440+-- >>> cube = fmap (\x -> x * x * x) Unfold.fromList
439−-- $ S.unfoldMany (UF.zipWith (,) UF.identity (UF.singleton sqrt))
441+-- >>> u = Unfold.zipWith (,) square cube
440−-- $ S.map (\x -> (x,x))
442+-- >>> Unfold.fold u Fold.toList [1..5]
441−-- $ S.fromList [1..10]
443+-- [(1,1),(4,8),(9,27),(16,64),(25,125)]
442−-- @
444+--
445+-- > zipWith f = zipWithM (\a b -> return $ f a b)
443--
446--
444-- /Pre-release/
447-- /Pre-release/
445--
448--
446{-# INLINE zipWith #-}
449{-# INLINE zipWith #-}
447zipWith :: Monad m
450zipWith :: Monad m
448− => (a -> b -> c) -> Unfold m x a -> Unfold m y b -> Unfold m (x, y) c
451+ => (b -> c -> d) -> Unfold m a b -> Unfold m a c -> Unfold m a d
449zipWith f = zipWithM (\a b -> return (f a b))
452zipWith f = zipWithM (\a b -> return (f a b))
450
453
454+-------------------------------------------------------------------------------
455+-- Arrow
456+-------------------------------------------------------------------------------
457+
451{-
458{-
452-- XXX There are multiple ways of combining the outputs of two unfolds, we
459-- XXX There are multiple ways of combining the outputs of two unfolds, we
453-- could zip, merge, append and more. What is the preferred way for Arrow
460-- could zip, merge, append and more. What is the preferred way for Arrow
@@ -464,5 +471,5 @@ instance Monad m => Arrow (Unfold m) where
464 arr = singleton
471 arr = singleton
465
472
466 {-# INLINE (***) #-}
473 {-# INLINE (***) #-}
467− (***) = zipWith (,)
474+ u1 *** u2 = zipWith (,) (lmap fst u1) (lmap snd u2)
468-}
475-}
test/Streamly/Test/Data/Unfold.hs+1−1
@@ -319,7 +319,7 @@ zipWithM =
319 unf2 = UF.enumerateFromToIntegral 20
319 unf2 = UF.enumerateFromToIntegral 20
320 fA = applyFun2 f :: Int -> Int -> Int
320 fA = applyFun2 f :: Int -> Int -> Int
321 fM a b = modify (+ 1) >> return (fA a b)
321 fM a b = modify (+ 1) >> return (fA a b)
322− unf = UF.zipWithM fM unf1 unf2
322+ unf = UF.zipWithM fM (UF.lmap fst unf1) (UF.lmap snd unf2)
323 lst = Prelude.zipWith fA [1 .. 10] [1 .. 20]
323 lst = Prelude.zipWith fA [1 .. 10] [1 .. 20]
324 in testUnfoldMD unf (1, 1) 0 10 lst
324 in testUnfoldMD unf (1, 1) 0 10 lst
325
325