on master help sign in
Change the iterateM implementation to use pure seed and add tests for it
149d263Abhiroop Sarkar
Changelog.md+2−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`
@@ -7,7 +8,7 @@
7
8
8### Enhancements
9### Enhancements
9* Make `cons` right associative and provide an operator form `.:` for it
10* Make `cons` right associative and provide an operator form `.:` for it
10−* Add `iterateM`, `iterate`, `null`, `tail`, `reverse`, `replicateM`, `scan` stream operations
11+* Add `null`, `tail`, `reverse`, `replicateM`, `scan` stream operations
11* Improve performance of some stream operations (`foldl`, `dropWhile`)
12* Improve performance of some stream operations (`foldl`, `dropWhile`)
12
13
13### Bug Fixes
14### Bug Fixes
src/Streamly/Prelude.hs+7−7
@@ -126,16 +126,16 @@ each = Prelude.foldr cons nil
126-- | Iterate a pure function from a seed value, streaming the results forever
126-- | Iterate a pure function from a seed value, streaming the results forever
127iterate :: Streaming t => (a -> a) -> a -> t m a
127iterate :: Streaming t => (a -> a) -> a -> t m a
128iterate step = fromStream . go
128iterate step = fromStream . go
129− where
129+ where
130− go s = scons s (Just (go (step s)))
130+ go s = scons s (Just (go (step s)))
131
131
132-- | Iterate a monadic function from a seed value, streaming the results forever
132-- | Iterate a monadic function from a seed value, streaming the results forever
133−iterateM :: (Streaming t, Monad m) => (a -> m a) -> m a -> t m a
133+iterateM :: (Streaming t, Monad m) => (a -> m a) -> a -> t m a
134iterateM step = fromStream . go
134iterateM step = fromStream . go
135− where
135+ where
136− go ms = Stream $ \_ _ yld -> do
136+ go s = Stream $ \_ _ yld -> do
137− s <- ms
137+ a <- step s
138− yld s (Just (go (step s)))
138+ yld s (Just (go a))
139
139
140-- | Read lines from an IO Handle into a stream of Strings.
140-- | Read lines from an IO Handle into a stream of Strings.
141fromHandle :: (Streaming t, MonadIO m) => IO.Handle -> t m String
141fromHandle :: (Streaming t, MonadIO m) => IO.Handle -> t m String
test/Main.hs+9−5
@@ -651,11 +651,15 @@ streamOperations (stream, list, len) = do
651 return $ str == lst
651 return $ str == lst
652 `shouldReturn` True
652 `shouldReturn` True
653
653
654− it "iterate" $ do
654+ it "iterate" $
655− let lst = take len $ iterate (+ 1) 0
655+ (A.toList . serially . (A.take len) $ (A.iterate (+ 1) (0 :: Int)))
656− str <- A.toList . serially . (A.take len) $ (A.iterate (+ 1) (0 :: Int))
656+ `shouldReturn` (take len $ iterate (+ 1) 0)
657+
658+ it "iterateM" $ do
657− return $ str == lst
659+ let addM = (\ y -> return (y + 1))
660+ A.toList . serially . (A.take len) $ A.iterateM addM (0 :: Int)
658− `shouldReturn` True
661+ `shouldReturn` (take len $ iterate (+ 1) 0)
662+
659
663
660 -- Filtering
664 -- Filtering
661 it "filter all out" $ transform (A.filter (> len)) (filter (> len))
665 it "filter all out" $ transform (A.filter (> len)) (filter (> len))