@@ -24,10 +24,11 @@ module Asyncly.Prelude
2424
2525 -- * Elimination
2626 , runStreaming
27− , toList
27+ , foldr
2828 , uncons
2929
3030 -- * Special folds
31+ , toList
3132 , take
3233 , drop
3334
@@ -41,27 +42,26 @@ where
4142
4243import Control.Monad (liftM)
4344import Data.Semigroup (Semigroup(..))
44−import Prelude hiding (drop, take, zipWith)
45+import Prelude hiding (drop, take, zipWith, foldr)
4546import Asyncly.Core
4647
4748------------------------------------------------------------------------------
4849-- Elimination
4950------------------------------------------------------------------------------
5051
51−-- | Collect the results of an 'AsyncT' stream into a list.
52−{-# INLINABLE toList #-}
53−toList :: (Monad m, Streaming t) => t m a -> m [a]
54−toList m = go (toStream m)
52+-- | Right fold a stream producing a result in the underlying monad.
53+foldr :: Streaming t => (a -> m b -> m b) -> m b -> t m a -> m b
54+foldr f z m = go (toStream m)
5555
5656 where
5757
5858 go m1 = (runStream m1) Nothing stop yield
5959
60− stop = return []
60+ stop = z
6161
6262 {-# INLINE yield #-}
63− yield a Nothing = return [a]
64− yield a (Just x) = liftM (a :) (go x)
63+ yield a Nothing = f a z
64+ yield a (Just x) = f a (go x)
6565
6666-- | Decompose a stream into its head and tail. If the stream is empty, returns
6767-- 'Nothing'. If the stream is non-empty, returns 'Just (a, ma)', where 'a' is
@@ -98,6 +98,11 @@ fromCallback k = Stream $ \_ _ yld -> k (\a -> yld a Nothing)
9898-- Special folds
9999------------------------------------------------------------------------------
100100
101+-- | Convert a stream into a list in the underlying monad.
102+{-# INLINABLE toList #-}
103+toList :: (Monad m, Streaming t) => t m a -> m [a]
104+toList = foldr (\a xs -> liftM (a :) xs) (return [])
105+
101106-- | Take first 'n' elements from the stream and discard the rest.
102107take :: Streaming t => Int -> t m a -> t m a
103108take n m = fromStream $ go n (toStream m)
@@ -124,7 +129,7 @@ drop n m = fromStream $ go n (toStream m)
124129-- Serially Zipping Streams
125130------------------------------------------------------------------------------
126131
127−-- | Zip two AsyncT streams serially using a monadic zipping function.
132+-- | Zip two streams serially using a monadic zipping function.
128133zipWithM :: Streaming t => (a -> b -> t m c) -> t m a -> t m b -> t m c
129134zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
130135 where
@@ -139,7 +144,7 @@ zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
139144 (runStream mx) Nothing stp yield1
140145 g a b = toStream $ f a b
141146
142−-- | Zip two AsyncT streams serially using a pure zipping function.
147+-- | Zip two streams serially using a pure zipping function.
143148zipWith :: Streaming t => (a -> b -> c) -> t m a -> t m b -> t m c
144149zipWith f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
145150 where
@@ -156,7 +161,7 @@ zipWith f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
156161-- Parallely Zipping Streams
157162------------------------------------------------------------------------------
158163
159−-- | Zip two AsyncT streams asyncly (i.e. both the streams are generated
164+-- | Zip two streams asyncly (i.e. both the elements being zipped are generated
160165-- concurrently) using a monadic zipping function.
161166zipAsyncWithM :: (Streaming t, MonadAsync m)
162167 => (a -> b -> t m c) -> t m a -> t m b -> t m c
@@ -165,7 +170,7 @@ zipAsyncWithM f m1 m2 = fromStream $ Stream $ \_ stp yld -> do
165170 mb <- async m2
166171 (runStream (toStream (zipWithM f ma mb))) Nothing stp yld
167172
168−-- | Zip two AsyncT streams asyncly (i.e. both the streams are generated
173+-- | Zip two streams asyncly (i.e. both the elements being zipped are generated
169174-- concurrently) using a pure zipping function.
170175zipAsyncWith :: (Streaming t, MonadAsync m)
171176 => (a -> b -> c) -> t m a -> t m b -> t m c