on master help sign in
Merge pull request #36 from Abhiroop/iterate
a9a7ea3Harendra Kumar
Changelog.md+1
@@ -1,4 +1,5 @@
1## Unreleased
1## Unreleased
2+* Add `iterate`, `iterateM` stream operations
2
3
3### Bug Fixes
4### Bug Fixes
4* Fix Zip/AsyncZip applicative instances to handle applicative injection of function like `pure f <*> s1 <*> s2`
5* Fix Zip/AsyncZip applicative instances to handle applicative injection of function like `pure f <*> s1 <*> s2`
src/Streamly/Prelude.hs+18−1
@@ -24,6 +24,8 @@ module Streamly.Prelude
24 , unfoldr
24 , unfoldr
25 , unfoldrM
25 , unfoldrM
26 , each
26 , each
27+ , iterate
28+ , iterateM
27
29
28 -- * Elimination
30 -- * Elimination
29 -- ** General Folds
31 -- ** General Folds
@@ -85,7 +87,8 @@ import Prelude hiding (filter, drop, dropWhile, take,
85 mapM, mapM_, sequence, all, any,
87 mapM, mapM_, sequence, all, any,
86 sum, product, elem, notElem,
88 sum, product, elem, notElem,
87 maximum, minimum, head, last,
89 maximum, minimum, head, last,
88− tail, length, null, reverse)
90+ tail, length, null, reverse,
91+ iterate)
89import qualified Prelude
92import qualified Prelude
90import qualified System.IO as IO
93import qualified System.IO as IO
91
94
@@ -120,6 +123,20 @@ unfoldrM step = fromStream . go
120each :: (Streaming t, Foldable f) => f a -> t m a
123each :: (Streaming t, Foldable f) => f a -> t m a
121each = Prelude.foldr cons nil
124each = Prelude.foldr cons nil
122
125
126+-- | Iterate a pure function from a seed value, streaming the results forever
127+iterate :: Streaming t => (a -> a) -> a -> t m a
128+iterate step = fromStream . go
129+ where
130+ go s = scons s (Just (go (step s)))
131+
132+-- | Iterate a monadic function from a seed value, streaming the results forever
133+iterateM :: (Streaming t, Monad m) => (a -> m a) -> a -> t m a
134+iterateM step = fromStream . go
135+ where
136+ go s = Stream $ \_ _ yld -> do
137+ a <- step s
138+ yld s (Just (go a))
139+
123-- | Read lines from an IO Handle into a stream of Strings.
140-- | Read lines from an IO Handle into a stream of Strings.
124fromHandle :: (Streaming t, MonadIO m) => IO.Handle -> t m String
141fromHandle :: (Streaming t, MonadIO m) => IO.Handle -> t m String
125fromHandle h = fromStream go
142fromHandle h = fromStream go
test/Main.hs+10
@@ -651,6 +651,16 @@ streamOperations (stream, list, len) = do
651 return $ str == lst
651 return $ str == lst
652 `shouldReturn` True
652 `shouldReturn` True
653
653
654+ it "iterate" $
655+ (A.toList . serially . (A.take len) $ (A.iterate (+ 1) (0 :: Int)))
656+ `shouldReturn` (take len $ iterate (+ 1) 0)
657+
658+ it "iterateM" $ do
659+ let addM = (\ y -> return (y + 1))
660+ A.toList . serially . (A.take len) $ A.iterateM addM (0 :: Int)
661+ `shouldReturn` (take len $ iterate (+ 1) 0)
662+
663+
654 -- Filtering
664 -- Filtering
655 it "filter all out" $ transform (A.filter (> len)) (filter (> len))
665 it "filter all out" $ transform (A.filter (> len)) (filter (> len))
656 it "filter all in" $ transform (A.filter (<= len)) (filter (<= len))
666 it "filter all in" $ transform (A.filter (<= len)) (filter (<= len))