on master help sign in
Add interleaved composition
5f1dc97Harendra Kumar
examples/loop.hs+9
@@ -9,22 +9,31 @@ import Asyncly
9main = do
9main = do
10 liftIO $ hSetBuffering stdout LineBuffering
10 liftIO $ hSetBuffering stdout LineBuffering
11
11
12+ putStrLn $ "\nloopTail:\n"
12 runAsyncly $ do
13 runAsyncly $ do
13 x <- loopTail (0 :: Int)
14 x <- loopTail (0 :: Int)
14 liftIO $ print x
15 liftIO $ print x
15
16
17+ putStrLn $ "\nloopHead:\n"
16 runAsyncly $ do
18 runAsyncly $ do
17 x <- loopHead (0 :: Int)
19 x <- loopHead (0 :: Int)
18 liftIO $ print x
20 liftIO $ print x
19
21
22+ putStrLn $ "\nloopTailA:\n"
20 runAsyncly $ do
23 runAsyncly $ do
21 x <- loopTailA (0 :: Int)
24 x <- loopTailA (0 :: Int)
22 liftIO $ print x
25 liftIO $ print x
23
26
27+ putStrLn $ "\nloopHeadA:\n"
24 runAsyncly $ do
28 runAsyncly $ do
25 x <- loopHeadA (0 :: Int)
29 x <- loopHeadA (0 :: Int)
26 liftIO $ print x
30 liftIO $ print x
27
31
32+ putStrLn $ "\ninterleave:\n"
33+ runAsyncly $ do
34+ x <- return (0 :: Int) <> return 1 <=> return 100 <> return 101
35+ liftIO $ print x
36+
28 where
37 where
29
38
30-------------------------------------------------------------------------------
39-------------------------------------------------------------------------------
src/Asyncly.hs+2
@@ -128,6 +128,8 @@ module Asyncly
128 , toList
128 , toList
129 , each
129 , each
130 , for
130 , for
131+ , interleave
132+ , (<=>)
131 )
133 )
132where
134where
133
135
src/Asyncly/AsyncT.hs+15
@@ -23,6 +23,8 @@ module Asyncly.AsyncT
23 , toList
23 , toList
24 , each
24 , each
25 , for
25 , for
26+ , interleave
27+ , (<=>)
26-- , async
28-- , async
27-- , makeAsync
29-- , makeAsync
28 )
30 )
@@ -122,6 +124,19 @@ instance Monad m => Monoid (AsyncT m a) where
122 yield a c (Just r) = yld a c (Just (mappend r m2))
124 yield a c (Just r) = yld a c (Just (mappend r m2))
123 in m1 ctx stop yield
125 in m1 ctx stop yield
124
126
127+-- | interleaves the results of two AsyncT computations
128+interleave :: AsyncT m a -> AsyncT m a -> AsyncT m a
129+interleave m1 m2 = AsyncT $ \ctx stp yld -> do
130+ let stop = (runAsyncT m2) ctx stp yld
131+ yield a c Nothing = yld a c (Just m2)
132+ yield a c (Just r) = yld a c (Just (interleave m2 r))
133+ (runAsyncT m1) ctx stop yield
134+
135+infixr 5 <=>
136+
137+(<=>) :: AsyncT m a -> AsyncT m a -> AsyncT m a
138+(<=>) = interleave
139+
125-- We do not use bind for parallelism. That is, we do not start each iteration
140-- We do not use bind for parallelism. That is, we do not start each iteration
126-- of the list in parallel. That will introduce too much uncontrolled
141-- of the list in parallel. That will introduce too much uncontrolled
127-- parallelism. Instead we control parallelism using <|>, it is used for
142-- parallelism. Instead we control parallelism using <|>, it is used for
test/Main.hs+3
@@ -22,6 +22,9 @@ main = hspec $ do
22 toList (return 0 <> return 1) `shouldReturn` ([0, 1] :: [Int])
22 toList (return 0 <> return 1) `shouldReturn` ([0, 1] :: [Int])
23 it "Monoid composition - each" $
23 it "Monoid composition - each" $
24 ((toList $ each [1..100]) >>= return . sort) `shouldReturn` ([1..100] :: [Int])
24 ((toList $ each [1..100]) >>= return . sort) `shouldReturn` ([1..100] :: [Int])
25+ it "Interleaved composition" $
26+ toList (return (0 :: Int) <> return 1 <=> return 100 <> return 101)
27+ `shouldReturn` ([0, 100, 1, 101])
25 it "simple runAsyncly and 'then' with IO" $
28 it "simple runAsyncly and 'then' with IO" $
26 runAsyncly (liftIO (putStrLn "hello") >> liftIO (putStrLn "world")) `shouldReturn` ()
29 runAsyncly (liftIO (putStrLn "hello") >> liftIO (putStrLn "world")) `shouldReturn` ()
27 it "Then and toList" $
30 it "Then and toList" $