@@ -12,7 +12,7 @@ import Control.Exception
1212import Control.Monad (when, forM_, replicateM, replicateM_)
1313import Control.Monad.IO.Class (MonadIO(..))
1414import Data.Function ((&))
15−import Data.IORef (readIORef, modifyIORef, newIORef)
15+import Data.IORef (readIORef, modifyIORef, newIORef, modifyIORef', IORef)
1616import Data.List
1717 (sort, foldl', scanl', findIndices, findIndex, elemIndices,
1818 elemIndex, find, insertBy, intersperse, foldl1', (\\),
@@ -146,15 +146,33 @@ constructWithDoubleFromThenTo op l =
146146 in constructWithLen stream list op l
147147#endif
148148
149−constructWithIterate :: IsStream t => (t IO Int -> SerialT IO Int) -> Spec
150−constructWithIterate t = do
151− it "iterate" $
152− (S.toList . t . S.take 100) (S.iterate (+ 1) (0 :: Int))
153− `shouldReturn` take 100 (iterate (+ 1) 0)
154− it "iterateM" $ do
155− let addM y = return (y + 1)
156− S.toList . t . S.take 100 $ S.iterateM addM (0 :: Int)
157− `shouldReturn` take 100 (iterate (+ 1) 0)
149+constructWithIterate ::
150+ IsStream t => (t IO Int -> SerialT IO Int) -> Word8 -> Property
151+constructWithIterate op len =
152+ withMaxSuccess maxTestCount $
153+ monadicIO $ do
154+ stream <-
155+ run $
156+ (S.toList . op . S.take (fromIntegral len))
157+ (S.iterate (+ 1) (0 :: Int))
158+ let list = take (fromIntegral len) (iterate (+ 1) 0)
159+ listEquals (==) stream list
160+
161+constructWithIterateM ::
162+ IsStream t => (t IO Int -> SerialT IO Int) -> Word8 -> Property
163+constructWithIterateM op len =
164+ withMaxSuccess maxTestCount $
165+ monadicIO $ do
166+ mvl <- run (newIORef [] :: IO (IORef [Int]))
167+ let addM mv x y = modifyIORef' mv (++ [y + x]) >> return (y + x)
168+ list = take (fromIntegral len) (iterate (+ 1) 0)
169+ run $
170+ S.drain . op $
171+ S.take (fromIntegral len) $
172+ S.iterateM (addM mvl 1) (addM mvl 0 0 :: IO Int)
173+ streamEffect <- run $ readIORef mvl
174+ listEquals (==) streamEffect list
175+
158176
159177-------------------------------------------------------------------------------
160178-- Concurrent generation
@@ -971,8 +989,18 @@ main = hspec
971989 serialOps $ prop "serially DoubleFromThenTo" .
972990 constructWithDoubleFromThenTo
973991#endif
992+
993+ serialOps $ prop "serially iterate" . constructWithIterate
994+
974995 -- XXX test for all types of streams
975− constructWithIterate serially
996+ serialOps $ prop "serially iterateM" . constructWithIterateM
997+ -- take doesn't work well on concurrent streams. Even though it
998+ -- seems like take only has a problem when used with parallely.
999+ -- wSerialOps $ prop "wSerially iterateM" wSerially . constructWithIterate
1000+ -- aheadOps $ prop "aheadly iterateM" aheadly . onstructWithIterate
1001+ -- asyncOps $ prop "asyncly iterateM" asyncly . constructWithIterate
1002+ -- wAsyncOps $ prop "wAsyncly iterateM" wAsyncly . onstructWithIterate
1003+ -- parallelOps $ prop "parallely iterateM" parallely . onstructWithIterate
9761004 -- XXX add tests for fromIndices
9771005
9781006 describe "Functor operations" $ do