@@ -14,20 +14,20 @@ import qualified Asyncly.Prelude as A
14main :: IO ()
14main :: IO ()
15main = hspec $ do
15main = hspec $ do
16 describe "Runners" $ do
16 describe "Runners" $ do
17− it "simple runAsyncly" $
17+ it "simple serially" $
18− runAsyncly (return (0 :: Int)) `shouldReturn` ()
18+ serially (return (0 :: Int)) `shouldReturn` ()
19− it "simple runAsyncly with IO" $
19+ it "simple serially with IO" $
20− runAsyncly (liftIO $ putStrLn "hello") `shouldReturn` ()
20+ serially (liftIO $ putStrLn "hello") `shouldReturn` ()
21 it "Captures a return value using toList" $
21 it "Captures a return value using toList" $
22− toList (return 0) `shouldReturn` ([0] :: [Int])
22+ toListSerial (return 0) `shouldReturn` ([0] :: [Int])
24 describe "Empty" $ do
24 describe "Empty" $ do
25 it "Monoid - mempty" $
25 it "Monoid - mempty" $
26− (toList mempty) `shouldReturn` ([] :: [Int])
26+ (toListSerial mempty) `shouldReturn` ([] :: [Int])
27 it "Alternative - empty" $
27 it "Alternative - empty" $
28− (toList empty) `shouldReturn` ([] :: [Int])
28+ (toListSerial empty) `shouldReturn` ([] :: [Int])
29 it "MonadPlus - mzero" $
29 it "MonadPlus - mzero" $
30− (toList mzero) `shouldReturn` ([] :: [Int])
30+ (toListSerial mzero) `shouldReturn` ([] :: [Int])
32 ---------------------------------------------------------------------------
32 ---------------------------------------------------------------------------
33 -- Functor
33 -- Functor
@@ -35,12 +35,12 @@ main = hspec $ do
36 describe "Functor (fmap)" $ do
36 describe "Functor (fmap)" $ do
37 it "Simple fmap" $
37 it "Simple fmap" $
38− (toList $ fmap (+1) (return 1)) `shouldReturn` ([2] :: [Int])
38+ (toListSerial $ fmap (+1) (return 1)) `shouldReturn` ([2] :: [Int])
39 it "fmap on composed (<>)" $
39 it "fmap on composed (<>)" $
40− (toList $ fmap (+1) (return 1 <> return 2))
40+ (toListSerial $ fmap (+1) (return 1 <> return 2))
41 `shouldReturn` ([2,3] :: [Int])
41 `shouldReturn` ([2,3] :: [Int])
42 it "fmap on composed (<|>)" $
42 it "fmap on composed (<|>)" $
43− (toList $ fmap (+1) (return 1 <|> return 2))
43+ (toListSerial $ fmap (+1) (return 1 <|> return 2))
44 `shouldReturn` ([2,3] :: [Int])
44 `shouldReturn` ([2,3] :: [Int])
46 ---------------------------------------------------------------------------
46 ---------------------------------------------------------------------------
@@ -49,23 +49,23 @@ main = hspec $ do
50 describe "Applicative" $ do
50 describe "Applicative" $ do
51 it "Simple apply" $
51 it "Simple apply" $
52− (toList $ (,) <$> (return 1) <*> (return 2))
52+ (toListSerial $ (,) <$> (return 1) <*> (return 2))
53 `shouldReturn` ([(1,2)] :: [(Int, Int)])
53 `shouldReturn` ([(1,2)] :: [(Int, Int)])
55 it "Apply - serial composed first argument" $
55 it "Apply - serial composed first argument" $
56− (toList $ (,) <$> (return 1 <> return 2) <*> (return 3))
56+ (toListSerial $ (,) <$> (return 1 <> return 2) <*> (return 3))
57 `shouldReturn` ([(1,3),(2,3)] :: [(Int, Int)])
57 `shouldReturn` ([(1,3),(2,3)] :: [(Int, Int)])
59 it "Apply - serial composed second argument" $
59 it "Apply - serial composed second argument" $
60− (toList $ (,) <$> (return 1) <*> (return 2 <> return 3))
60+ (toListSerial $ (,) <$> (return 1) <*> (return 2 <> return 3))
61 `shouldReturn` ([(1,2),(1,3)] :: [(Int, Int)])
61 `shouldReturn` ([(1,2),(1,3)] :: [(Int, Int)])
63 it "Apply - parallel composed first argument" $
63 it "Apply - parallel composed first argument" $
64− (toList $ (,) <$> (return 1 <|> return 2) <*> (return 3))
64+ (toListSerial $ (,) <$> (return 1 <|> return 2) <*> (return 3))
65 `shouldReturn` ([(1,3),(2,3)] :: [(Int, Int)])
65 `shouldReturn` ([(1,3),(2,3)] :: [(Int, Int)])
67 it "Apply - parallel composed second argument" $
67 it "Apply - parallel composed second argument" $
68− (toList $ (,) <$> (return 1) <*> (return 2 <|> return 3))
68+ (toListSerial $ (,) <$> (return 1) <*> (return 2 <|> return 3))
69 `shouldReturn` ([(1,2),(1,3)] :: [(Int, Int)])
69 `shouldReturn` ([(1,2),(1,3)] :: [(Int, Int)])
71 ---------------------------------------------------------------------------
71 ---------------------------------------------------------------------------
@@ -73,15 +73,15 @@ main = hspec $ do
73 ---------------------------------------------------------------------------
73 ---------------------------------------------------------------------------
75 describe "Bind then" thenBind
75 describe "Bind then" thenBind
76− describe "Pure bind serial" $ pureBind (>>=)
76+ describe "Pure bind serial" $ pureBind toListSerial
77− describe "Pure bind serial interleaved" $ pureBind (>->)
77+ describe "Pure bind serial interleaved" $ pureBind toListInterleaved
78− describe "Pure bind parallel DFS" $ pureBind (>>|)
78+ describe "Pure bind parallel DFS" $ pureBind toListAsync
79− describe "Pure bind parallel BFS" $ pureBind (>|>)
79+ describe "Pure bind parallel BFS" $ pureBind toListParallel
81− describe "Bind (>>=) with empty" $ bindEmpty (>>=)
81+ describe "Bind (>>=) with empty" $ bindEmpty toListSerial
82− describe "Bind (>->) with empty" $ bindEmpty (>->)
82+ describe "Bind (>->) with empty" $ bindEmpty toListInterleaved
83− describe "Bind (>|>) with empty" $ bindEmpty (>|>)
83+ describe "Bind (>|>) with empty" $ bindEmpty toListAsync
84− describe "Bind (>>|) with empty" $ bindEmpty (>>|)
84+ describe "Bind (>>|) with empty" $ bindEmpty toListParallel
86 ---------------------------------------------------------------------------
86 ---------------------------------------------------------------------------
87 -- Monoidal Compositions
87 -- Monoidal Compositions
@@ -98,8 +98,8 @@ main = hspec $ do
98 -- Monoidal Composition ordering checks
98 -- Monoidal Composition ordering checks
99 ---------------------------------------------------------------------------
99 ---------------------------------------------------------------------------
101− describe "Serial interleaved ordering check (<=>)" $ interleaved (<=>)
101+ describe "Serial interleaved ordering check (<=>)" $ interleaveCheck (<=>)
102− describe "Parallel interleaved ordering check (<|>)" $ interleaved (<|>)
102+ describe "Parallel interleaved ordering check (<|>)" $ interleaveCheck (<|>)
103 describe "Left biased parallel time order check" $ parallelCheck (<|)
103 describe "Left biased parallel time order check" $ parallelCheck (<|)
104 describe "Fair parallel time order check" $ parallelCheck (<|>)
104 describe "Fair parallel time order check" $ parallelCheck (<|>)
@@ -140,13 +140,13 @@ main = hspec $ do
140 describe "Nested parallel and serial compositions" $ do
140 describe "Nested parallel and serial compositions" $ do
141 it "Nest <|>, <>, <|> (1)" $
141 it "Nest <|>, <>, <|> (1)" $
142 let t = timed
142 let t = timed
143− in toList (
143+ in toListSerial (
144 ((t 8 <|> t 4) <> (t 2 <|> t 0))
144 ((t 8 <|> t 4) <> (t 2 <|> t 0))
145 <|> ((t 8 <|> t 4) <> (t 2 <|> t 0)))
145 <|> ((t 8 <|> t 4) <> (t 2 <|> t 0)))
146 `shouldReturn` ([4,4,8,8,0,0,2,2])
146 `shouldReturn` ([4,4,8,8,0,0,2,2])
147 it "Nest <|>, <>, <|> (2)" $
147 it "Nest <|>, <>, <|> (2)" $
148 let t = timed
148 let t = timed
149− in toList (
149+ in toListSerial (
150 ((t 4 <|> t 8) <> (t 1 <|> t 2))
150 ((t 4 <|> t 8) <> (t 1 <|> t 2))
151 <|> ((t 4 <|> t 8) <> (t 1 <|> t 2)))
151 <|> ((t 4 <|> t 8) <> (t 1 <|> t 2)))
152 `shouldReturn` ([4,4,8,8,1,1,2,2])
152 `shouldReturn` ([4,4,8,8,1,1,2,2])
@@ -155,20 +155,20 @@ main = hspec $ do
156 it "Nest <|>, <=>, <|> (1)" $
156 it "Nest <|>, <=>, <|> (1)" $
157 let t = timed
157 let t = timed
158− in toList (
158+ in toListSerial (
159 ((t 8 <|> t 4) <=> (t 2 <|> t 0))
159 ((t 8 <|> t 4) <=> (t 2 <|> t 0))
160 <|> ((t 9 <|> t 4) <=> (t 2 <|> t 0)))
160 <|> ((t 9 <|> t 4) <=> (t 2 <|> t 0)))
161 `shouldReturn` ([4,4,0,0,8,2,9,2])
161 `shouldReturn` ([4,4,0,0,8,2,9,2])
162 it "Nest <|>, <=>, <|> (2)" $
162 it "Nest <|>, <=>, <|> (2)" $
163 let t = timed
163 let t = timed
164− in toList (
164+ in toListSerial (
165 ((t 4 <|> t 8) <=> (t 1 <|> t 2))
165 ((t 4 <|> t 8) <=> (t 1 <|> t 2))
166 <|> ((t 4 <|> t 9) <=> (t 1 <|> t 2)))
166 <|> ((t 4 <|> t 9) <=> (t 1 <|> t 2)))
167 `shouldReturn` ([4,4,1,1,8,2,9,2])
167 `shouldReturn` ([4,4,1,1,8,2,9,2])
169 it "Nest <|>, <|>, <|>" $
169 it "Nest <|>, <|>, <|>" $
170 let t = timed
170 let t = timed
171− in toList (
171+ in toListSerial (
172 ((t 4 <|> t 8) <|> (t 0 <|> t 2))
172 ((t 4 <|> t 8) <|> (t 0 <|> t 2))
173 <|> ((t 4 <|> t 8) <|> (t 0 <|> t 2)))
173 <|> ((t 4 <|> t 8) <|> (t 0 <|> t 2)))
174 `shouldReturn` ([0,0,2,2,4,4,8,8])
174 `shouldReturn` ([0,0,2,2,4,4,8,8])
@@ -185,17 +185,37 @@ main = hspec $ do
185 -- Bind and monoidal composition combinations
185 -- Bind and monoidal composition combinations
186 ---------------------------------------------------------------------------
186 ---------------------------------------------------------------------------
188− forM_ [(>>=), (>->), (>>|), (>|>)] $ \f ->
188+ forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
189+ describe "Bind and compose" $ bindAndComposeSimple toListSerial g
191+ forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
192+ describe "Bind and compose" $ bindAndComposeSimple toListInterleaved g
194+ forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
195+ describe "Bind and compose" $ bindAndComposeSimple toListAsync g
189− forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
197+ forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
190− describe "Bind and compose" $ bindAndComposeSimple f g
198+ describe "Bind and compose" $ bindAndComposeSimple toListParallel g
192 let fldr f = foldr f empty
200 let fldr f = foldr f empty
193 fldl f = foldl f empty
201 fldl f = foldl f empty
194− in forM_ [(>>=), (>->), (>>|), (>|>)] $ \f ->
203+ forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
195− forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
204+ forM_ [fldr, fldl] $ \k ->
205+ describe "Bind and compose" $
206+ bindAndComposeHierarchy toListSerial (k g)
207+ forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
208+ forM_ [fldr, fldl] $ \k ->
209+ describe "Bind and compose" $
210+ bindAndComposeHierarchy toListInterleaved (k g)
211+ forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
196− forM_ [fldr, fldl] $ \k ->
212+ forM_ [fldr, fldl] $ \k ->
213+ describe "Bind and compose" $
214+ bindAndComposeHierarchy toListAsync (k g)
215+ forM_ [(<>), (<=>), (<|), (<|>)] $ \g ->
216+ forM_ [fldr, fldl] $ \k ->
197− describe "Bind and compose" $
217+ describe "Bind and compose" $
198− bindAndComposeHierarchy f (k g)
218+ bindAndComposeHierarchy toListParallel (k g)
200 ---------------------------------------------------------------------------
220 ---------------------------------------------------------------------------
201 -- TBD Bind and Bind combinations
221 -- TBD Bind and Bind combinations
@@ -206,149 +226,153 @@ main = hspec $ do
207 describe "Transformation" $ transformOps (<>)
227 describe "Transformation" $ transformOps (<>)
208 describe "Serial zipping" $
228 describe "Serial zipping" $
209− zipOps A.zipWith A.zipWithM A.ZipSerial A.getZipSerial
229+ zipOps A.zipWith A.zipWithM fromStream fromZipStream
210 describe "Async zipping" $
230 describe "Async zipping" $
211− zipOps A.zipAsyncWith A.zipAsyncWithM A.ZipAsync A.getZipAsync
231+ zipOps A.zipAsyncWith A.zipAsyncWithM fromStream fromZipAsync
213zipOps :: Applicative (f IO)
233zipOps :: Applicative (f IO)
214 => (forall a b c. (a -> b -> c)
234 => (forall a b c. (a -> b -> c)
215− -> AsyncT IO a -> AsyncT IO b -> AsyncT IO c)
235+ -> StreamT IO a -> StreamT IO b -> StreamT IO c)
216− -> (forall a b c. (a -> b -> AsyncT IO c)
236+ -> (forall a b c. (a -> b -> StreamT IO c)
217− -> AsyncT IO a -> AsyncT IO b -> AsyncT IO c)
237+ -> StreamT IO a -> StreamT IO b -> StreamT IO c)
218− -> (forall a. AsyncT IO a -> f IO a)
238+ -> (forall a. StreamT IO a -> f IO a)
219− -> (forall a. f IO a -> AsyncT IO a)
239+ -> (forall a. f IO a -> StreamT IO a)
221zipOps z zM app getz = do
241zipOps z zM app getz = do
222 it "zipWith" $
242 it "zipWith" $
223 let s1 = foldMapWith (<|>) return [1..10]
243 let s1 = foldMapWith (<|>) return [1..10]
224 s2 = foldMapWith (<>) return [1..]
244 s2 = foldMapWith (<>) return [1..]
225− in toList (z (+) s1 s2)
245+ in toListSerial (z (+) s1 s2)
226 `shouldReturn` ([2,4..20] :: [Int])
246 `shouldReturn` ([2,4..20] :: [Int])
228 it "zipWithM" $
248 it "zipWithM" $
229 let s1 = foldMapWith (<|>) return [1..10]
249 let s1 = foldMapWith (<|>) return [1..10]
230 s2 = foldMapWith (<>) return [1..]
250 s2 = foldMapWith (<>) return [1..]
231− in toList (zM (\a b -> return (a + b)) s1 s2)
251+ in toListSerial (zM (\a b -> return (a + b)) s1 s2)
232 `shouldReturn` ([2,4..20] :: [Int])
252 `shouldReturn` ([2,4..20] :: [Int])
234 it "Applicative zip" $
254 it "Applicative zip" $
235 let s1 = foldMapWith (<|>) return [1..10]
255 let s1 = foldMapWith (<|>) return [1..10]
236 s2 = foldMapWith (<>) return [1..]
256 s2 = foldMapWith (<>) return [1..]
237− in toList (getz ((+) <$> app s1 <*> app s2))
257+ in toListSerial (getz ((+) <$> app s1 <*> app s2))
238 `shouldReturn` ([2,4..20] :: [Int])
258 `shouldReturn` ([2,4..20] :: [Int])
240−timed :: Int -> AsyncT IO Int
260+timed :: Int -> StreamT IO Int
241timed x = liftIO (threadDelay (x * 100000)) >> return x
261timed x = liftIO (threadDelay (x * 100000)) >> return x
243thenBind :: Spec
263thenBind :: Spec
244thenBind = do
264thenBind = do
245 it "Simple runAsyncly and 'then' with IO" $
265 it "Simple runAsyncly and 'then' with IO" $
246− runAsyncly (liftIO (putStrLn "hello") >> liftIO (putStrLn "world"))
266+ serially (liftIO (putStrLn "hello") >> liftIO (putStrLn "world"))
247 `shouldReturn` ()
267 `shouldReturn` ()
248 it "Then and toList" $
268 it "Then and toList" $
249− toList (return (1 :: Int) >> return 2) `shouldReturn` ([2] :: [Int])
269+ toListSerial (return (1 :: Int) >> return 2) `shouldReturn` ([2] :: [Int])
251−pureBind :: (AsyncT IO Int -> (Int -> AsyncT IO Int) -> AsyncT IO Int) -> Spec
271+type ToListType s = (forall a. s IO a -> IO [a])
272+pureBind :: Monad (s IO) => ToListType s -> Spec
252−pureBind f = do
273+pureBind l = do
253 it "Bind and toList" $
274 it "Bind and toList" $
254− toList (return 1 `f` \x -> return 2 `f` \y -> return (x + y))
275+ l (return 1 `f` \x -> return 2 `f` \y -> return (x + y))
255 `shouldReturn` ([3] :: [Int])
276 `shouldReturn` ([3] :: [Int])
257−bindEmpty :: (AsyncT IO Int -> (Int -> AsyncT IO Int) -> AsyncT IO Int) -> Spec
279+bindEmpty :: (Monad (s IO), Alternative (s IO)) => ToListType s -> Spec
258−bindEmpty f = it "Binds with empty" $
280+bindEmpty l = it "Binds with empty" $
259− (toList (return 1 `f` \_ -> empty `f` \_ -> return 2))
281+ (l (return (1 :: Int) `f` \_ -> empty `f` \_ -> return 2))
260 `shouldReturn` ([] :: [Int])
282 `shouldReturn` ([] :: [Int])
262−interleaved
285+interleaveCheck
263− :: (AsyncT IO Int -> AsyncT IO Int -> AsyncT IO Int)
286+ :: (StreamT IO Int -> StreamT IO Int -> StreamT IO Int)
265−interleaved f =
288+interleaveCheck f =
266 it "Interleave four" $
289 it "Interleave four" $
267− toList ((return 0 <> return 1) `f` (return 100 <> return 101))
290+ toListSerial ((return 0 <> return 1) `f` (return 100 <> return 101))
268 `shouldReturn` ([0, 100, 1, 101])
291 `shouldReturn` ([0, 100, 1, 101])
270−parallelCheck :: (AsyncT IO Int -> AsyncT IO Int -> AsyncT IO Int) -> Spec
293+parallelCheck :: (StreamT IO Int -> StreamT IO Int -> StreamT IO Int) -> Spec
271parallelCheck f = do
294parallelCheck f = do
272 it "Parallel ordering left associated" $
295 it "Parallel ordering left associated" $
273− toList (((event 4 `f` event 3) `f` event 2) `f` event 1)
296+ toListSerial (((event 4 `f` event 3) `f` event 2) `f` event 1)
274 `shouldReturn` ([1..4])
297 `shouldReturn` ([1..4])
276 it "Parallel ordering right associated" $
299 it "Parallel ordering right associated" $
277− toList (event 4 `f` (event 3 `f` (event 2 `f` event 1)))
300+ toListSerial (event 4 `f` (event 3 `f` (event 2 `f` event 1)))
278 `shouldReturn` ([1..4])
301 `shouldReturn` ([1..4])
280 where event n = (liftIO $ threadDelay (n * 100000)) >> (return n)
303 where event n = (liftIO $ threadDelay (n * 100000)) >> (return n)
283− :: (AsyncT IO Int -> AsyncT IO Int -> AsyncT IO Int)
306+ :: (StreamT IO Int -> StreamT IO Int -> StreamT IO Int)
284 -> ([Int] -> [Int])
307 -> ([Int] -> [Int])
286compose f srt = do
309compose f srt = do
287 it "Compose mempty, mempty" $
310 it "Compose mempty, mempty" $
288− (toList (mempty `f` mempty)) `shouldReturn` []
311+ (tl (mempty `f` mempty)) `shouldReturn` []
289 it "Compose empty, empty" $
312 it "Compose empty, empty" $
290− (toList (empty `f` empty)) `shouldReturn` []
313+ (tl (empty `f` empty)) `shouldReturn` []
291 it "Compose empty at the beginning" $
314 it "Compose empty at the beginning" $
292− (toList $ (empty `f` return 1)) `shouldReturn` [1]
315+ (tl $ (empty `f` return 1)) `shouldReturn` [1]
293 it "Compose empty at the end" $
316 it "Compose empty at the end" $
294− (toList $ (return 1 `f` empty)) `shouldReturn` [1]
317+ (tl $ (return 1 `f` empty)) `shouldReturn` [1]
295 it "Compose two" $
318 it "Compose two" $
296− (toList (return 0 `f` return 1) >>= return . srt)
319+ (tl (return 0 `f` return 1) >>= return . srt)
297 `shouldReturn` [0, 1]
320 `shouldReturn` [0, 1]
298 it "Compose three - empty in the middle" $
321 it "Compose three - empty in the middle" $
299− ((toList $ (return 0 `f` empty `f` return 1)) >>= return . srt)
322+ ((tl $ (return 0 `f` empty `f` return 1)) >>= return . srt)
300 `shouldReturn` [0, 1]
323 `shouldReturn` [0, 1]
301 it "Compose left associated" $
324 it "Compose left associated" $
302− ((toList $ (((return 0 `f` return 1) `f` return 2) `f` return 3))
325+ ((tl $ (((return 0 `f` return 1) `f` return 2) `f` return 3))
303 >>= return . srt) `shouldReturn` [0, 1, 2, 3]
326 >>= return . srt) `shouldReturn` [0, 1, 2, 3]
304 it "Compose right associated" $
327 it "Compose right associated" $
305− ((toList $ (return 0 `f` (return 1 `f` (return 2 `f` return 3))))
328+ ((tl $ (return 0 `f` (return 1 `f` (return 2 `f` return 3))))
306 >>= return . srt) `shouldReturn` [0, 1, 2, 3]
329 >>= return . srt) `shouldReturn` [0, 1, 2, 3]
307 it "Compose many" $
330 it "Compose many" $
308− ((toList $ forEachWith f [1..100] return) >>= return . srt)
331+ ((tl $ forEachWith f [1..100] return) >>= return . srt)
309 `shouldReturn` [1..100]
332 `shouldReturn` [1..100]
310 it "Compose hierarchical (multiple levels)" $
333 it "Compose hierarchical (multiple levels)" $
311− ((toList $ (((return 0 `f` return 1) `f` (return 2 `f` return 3))
334+ ((tl $ (((return 0 `f` return 1) `f` (return 2 `f` return 3))
312 `f` ((return 4 `f` return 5) `f` (return 6 `f` return 7)))
335 `f` ((return 4 `f` return 5) `f` (return 6 `f` return 7)))
313 ) >>= return . srt) `shouldReturn` [0..7]
336 ) >>= return . srt) `shouldReturn` [0..7]
337+ where tl = toListSerial
315composeAndComposeSimple
339composeAndComposeSimple
316− :: (AsyncT IO Int -> AsyncT IO Int -> AsyncT IO Int)
340+ :: (StreamT IO Int -> StreamT IO Int -> StreamT IO Int)
317− -> (AsyncT IO Int -> AsyncT IO Int -> AsyncT IO Int)
341+ -> (StreamT IO Int -> StreamT IO Int -> StreamT IO Int)
318 -> [[Int]]
342 -> [[Int]]
320composeAndComposeSimple f g answer = do
344composeAndComposeSimple f g answer = do
321 it "Compose right associated outer expr, right folded inner" $
345 it "Compose right associated outer expr, right folded inner" $
322 let fold = foldMapWith g return
346 let fold = foldMapWith g return
323− in (toList (fold [1,2,3] `f` (fold [4,5,6] `f` fold [7,8,9])))
347+ in (toListSerial (fold [1,2,3] `f` (fold [4,5,6] `f` fold [7,8,9])))
324 `shouldReturn` (answer !! 0)
348 `shouldReturn` (answer !! 0)
326 it "Compose left associated outer expr, right folded inner" $
350 it "Compose left associated outer expr, right folded inner" $
327 let fold = foldMapWith g return
351 let fold = foldMapWith g return
328− in (toList ((fold [1,2,3] `f` fold [4,5,6]) `f` fold [7,8,9]))
352+ in (toListSerial ((fold [1,2,3] `f` fold [4,5,6]) `f` fold [7,8,9]))
329 `shouldReturn` (answer !! 1)
353 `shouldReturn` (answer !! 1)
331 it "Compose right associated outer expr, left folded inner" $
355 it "Compose right associated outer expr, left folded inner" $
332 let fold xs = foldl g empty $ map return xs
356 let fold xs = foldl g empty $ map return xs
333− in (toList (fold [1,2,3] `f` (fold [4,5,6] `f` fold [7,8,9])))
357+ in (toListSerial (fold [1,2,3] `f` (fold [4,5,6] `f` fold [7,8,9])))
334 `shouldReturn` (answer !! 2)
358 `shouldReturn` (answer !! 2)
336 it "Compose left associated outer expr, left folded inner" $
360 it "Compose left associated outer expr, left folded inner" $
337 let fold xs = foldl g empty $ map return xs
361 let fold xs = foldl g empty $ map return xs
338− in (toList ((fold [1,2,3] `f` fold [4,5,6]) `f` fold [7,8,9]))
362+ in (toListSerial ((fold [1,2,3] `f` fold [4,5,6]) `f` fold [7,8,9]))
339 `shouldReturn` (answer !! 3)
363 `shouldReturn` (answer !! 3)
343− :: (AsyncT IO Int -> AsyncT IO Int -> AsyncT IO Int)
367+ :: (StreamT IO Int -> StreamT IO Int -> StreamT IO Int)
344 -> ([Int] -> [Int])
368 -> ([Int] -> [Int])
345 -> ([Int] -> [Int])
369 -> ([Int] -> [Int])
347loops f tsrt hsrt = do
371loops f tsrt hsrt = do
348− it "Tail recursive loop" $ (toList (loopTail 0) >>= return . tsrt)
372+ it "Tail recursive loop" $ (toListSerial (loopTail 0) >>= return . tsrt)
349 `shouldReturn` [0..3]
373 `shouldReturn` [0..3]
351− it "Head recursive loop" $ (toList (loopHead 0) >>= return . hsrt)
375+ it "Head recursive loop" $ (toListSerial (loopHead 0) >>= return . hsrt)
352 `shouldReturn` [0..3]
376 `shouldReturn` [0..3]
@@ -363,26 +387,27 @@ loops f tsrt hsrt = do
363 return x `f` (if x < 3 then loopTail (x + 1) else empty)
387 return x `f` (if x < 3 then loopTail (x + 1) else empty)
365bindAndComposeSimple
389bindAndComposeSimple
366− :: (AsyncT IO Int -> (Int -> AsyncT IO Int) -> AsyncT IO Int)
390+ :: (Alternative (s IO), Monad (s IO), Monoid (s IO Int)) => (forall a. s IO a -> IO [a])
367− -> (AsyncT IO Int -> AsyncT IO Int -> AsyncT IO Int)
391+ -> (s IO Int -> s IO Int -> s IO Int)
369−bindAndComposeSimple f g = do
393+bindAndComposeSimple tl g = do
370 it "Compose many (right fold) with bind" $
394 it "Compose many (right fold) with bind" $
371− (toList (forEachWith g [1..10 :: Int] $ \x -> return x `f` (return . id))
395+ (tl (forEachWith g [1..10 :: Int] $ \x -> return x `f` (return . id))
372 >>= return . sort) `shouldReturn` [1..10]
396 >>= return . sort) `shouldReturn` [1..10]
374 it "Compose many (left fold) with bind" $
398 it "Compose many (left fold) with bind" $
375 let forL xs k = foldl g empty $ map k xs
399 let forL xs k = foldl g empty $ map k xs
376− in (toList (forL [1..10 :: Int] $ \x -> return x `f` (return . id))
400+ in (tl (forL [1..10 :: Int] $ \x -> return x `f` (return . id))
377 >>= return . sort) `shouldReturn` [1..10]
401 >>= return . sort) `shouldReturn` [1..10]
379bindAndComposeHierarchy
404bindAndComposeHierarchy
380− :: (AsyncT IO Int -> (Int -> AsyncT IO Int) -> AsyncT IO Int)
405+ :: Monad (s IO) => (forall a. s IO a -> IO [a])
381− -> ([AsyncT IO Int] -> AsyncT IO Int)
406+ -> ([s IO Int] -> s IO Int)
383−bindAndComposeHierarchy f g = do
408+bindAndComposeHierarchy tl g = do
384 it "Bind and compose nested" $
409 it "Bind and compose nested" $
385− (toList bindComposeNested >>= return . sort)
410+ (tl bindComposeNested >>= return . sort)
386 `shouldReturn` (sort (
411 `shouldReturn` (sort (
388 ++ replicate 3 13
413 ++ replicate 3 13
@@ -393,7 +418,7 @@ bindAndComposeHierarchy f g = do
396− bindComposeNested :: AsyncT IO Int
421+ -- bindComposeNested :: AsyncT IO Int
397 bindComposeNested =
422 bindComposeNested =
398 let c1 = tripleCompose (return 1) (return 2) (return 3)
423 let c1 = tripleCompose (return 1) (return 2) (return 3)
399 c2 = tripleCompose (return 4) (return 5) (return 6)
424 c2 = tripleCompose (return 4) (return 5) (return 6)
@@ -410,17 +435,18 @@ bindAndComposeHierarchy f g = do
410 mx `f` \x -> my
435 mx `f` \x -> my
411 `f` \y -> mz
436 `f` \y -> mz
412 `f` \z -> return (x + y + z)
437 `f` \z -> return (x + y + z)
414mixedOps :: Spec
440mixedOps :: Spec
415mixedOps = do
441mixedOps = do
416 it "Compose many ops" $
442 it "Compose many ops" $
417− (toList composeMixed >>= return . sort)
443+ (toListSerial composeMixed >>= return . sort)
418 `shouldReturn` ([8,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,11,11
444 `shouldReturn` ([8,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,11,11
419 ,11,11,11,11,11,11,11,11,12,12,12,12,12,13
445 ,11,11,11,11,11,11,11,11,12,12,12,12,12,13
420 ] :: [Int])
446 ] :: [Int])
423− composeMixed :: AsyncT IO Int
449+ composeMixed :: StreamT IO Int
424 composeMixed = do
450 composeMixed = do
425 liftIO $ return ()
451 liftIO $ return ()
426 liftIO $ putStr ""
452 liftIO $ putStr ""
@@ -441,24 +467,24 @@ mixedOps = do
441 return (x1 + y1 + z1)
467 return (x1 + y1 + z1)
442 return (x + y + z)
468 return (x + y + z)
444−transformOps :: (AsyncT IO Int -> AsyncT IO Int -> AsyncT IO Int) -> Spec
470+transformOps :: (StreamT IO Int -> StreamT IO Int -> StreamT IO Int) -> Spec
445transformOps f = do
471transformOps f = do
446 it "take all" $
472 it "take all" $
447− (toList $ A.take 10 $ foldMapWith f return [1..10])
473+ (toListSerial $ A.take 10 $ foldMapWith f return [1..10])
448 `shouldReturn` [1..10]
474 `shouldReturn` [1..10]
449 it "take none" $
475 it "take none" $
450− (toList $ A.take 0 $ foldMapWith f return [1..10])
476+ (toListSerial $ A.take 0 $ foldMapWith f return [1..10])
451 `shouldReturn` []
477 `shouldReturn` []
452 it "take 5" $
478 it "take 5" $
453− (toList $ A.take 5 $ foldMapWith f return [1..10])
479+ (toListSerial $ A.take 5 $ foldMapWith f return [1..10])
454 `shouldReturn` [1..5]
480 `shouldReturn` [1..5]
456 it "drop all" $
482 it "drop all" $
457− (toList $ A.drop 10 $ foldMapWith f return [1..10])
483+ (toListSerial $ A.drop 10 $ foldMapWith f return [1..10])
458 `shouldReturn` []
484 `shouldReturn` []
459 it "drop none" $
485 it "drop none" $
460− (toList $ A.drop 0 $ foldMapWith f return [1..10])
486+ (toListSerial $ A.drop 0 $ foldMapWith f return [1..10])
461 `shouldReturn` [1..10]
487 `shouldReturn` [1..10]
462 it "drop 5" $
488 it "drop 5" $
463− (toList $ A.drop 5 $ foldMapWith f return [1..10])
489+ (toListSerial $ A.drop 5 $ foldMapWith f return [1..10])
464 `shouldReturn` [6..10]
490 `shouldReturn` [6..10]