on master help sign in
Merge pull request #36 from Abhiroop/iterate

Iterate

commita9a7ea3aee2f7297dd0a6dd2d859ce3546ae90b3 authorHarendra Kumar <harendra.kumar@gmail.com> dateSun 25 Mar 2018, 03:15 (9 years ago) parent398022e9cac526
3 files changed+29−1
Changelog.md+1 src/Streamly/Prelude.hs+18−1 test/Main.hs+10
Changelog.md+1
@@ -1,4 +1,5 @@
11## Unreleased
2+* Add `iterate`, `iterateM` stream operations
23
34### Bug Fixes
45* 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
2424 , unfoldr
2525 , unfoldrM
2626 , each
27+ , iterate
28+ , iterateM
2729
2830 -- * Elimination
2931 -- ** General Folds
@@ -85,7 +87,8 @@ import Prelude hiding (filter, drop, dropWhile, take,
8587 mapM, mapM_, sequence, all, any,
8688 sum, product, elem, notElem,
8789 maximum, minimum, head, last,
88− tail, length, null, reverse)
90+ tail, length, null, reverse,
91+ iterate)
8992import qualified Prelude
9093import qualified System.IO as IO
9194
@@ -120,6 +123,20 @@ unfoldrM step = fromStream . go
120123each :: (Streaming t, Foldable f) => f a -> t m a
121124each = Prelude.foldr cons nil
122125
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+
123140-- | Read lines from an IO Handle into a stream of Strings.
124141fromHandle :: (Streaming t, MonadIO m) => IO.Handle -> t m String
125142fromHandle h = fromStream go
test/Main.hs+10
@@ -651,6 +651,16 @@ streamOperations (stream, list, len) = do
651651 return $ str == lst
652652 `shouldReturn` True
653653
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+
654664 -- Filtering
655665 it "filter all out" $ transform (A.filter (> len)) (filter (> len))
656666 it "filter all in" $ transform (A.filter (<= len)) (filter (<= len))