@@ -51,13 +51,29 @@ newtype AsyncT m a =
5151-- Monad
5252------------------------------------------------------------------------------
5353
54+-- We do not use bind for parallelism. That is, we do not start each iteration
55+-- of the list in parallel. That will introduce too much uncontrolled
56+-- parallelism. Instead we control parallelsim using <|>, it is used for
57+-- actions that 'may' be run in parallel. The library decides whether they will
58+-- be started in parallel. This puts the parallel semantics in the hands of the
59+-- user and operational semantics in the hands of the library. Ideally we would
60+-- want parallelism to be completely hidden from the user, for example we can
61+-- automatically decide where to start an action in parallel so that it is most
62+-- efficient. Maybe sometime we shall be able to do that?
63+
64+serially :: AsyncT m a -> AsyncT m a -> AsyncT m a
65+serially (AsyncT m1) m2 = AsyncT $ \stp yld ->
66+ m1 ((runAsyncT m2) stp yld) $ \a r ->
67+ let yield x = yld a (Just x)
68+ in maybe (yield m2) (\rx -> yield $ serially rx m2) r
69+
5470instance Monad m => Monad (AsyncT m) where
5571 return a = AsyncT $ \_ yld -> yld a Nothing
5672
5773 AsyncT m >>= f = AsyncT $ \stp yld ->
5874 let run x = (runAsyncT x) stp yld
5975 in m stp $ \a r ->
60− maybe (run $ f a) (\rx -> run $ f a <|> (rx >>= f)) r
76+ maybe (run $ f a) (\rx -> run $ serially (f a) (rx >>= f)) r
6177
6278------------------------------------------------------------------------------
6379-- Functor