@@ -10,6 +10,16 @@
10{-# LANGUAGE TypeFamilies #-}
10{-# LANGUAGE TypeFamilies #-}
11{-# LANGUAGE UndecidableInstances #-}
11{-# LANGUAGE UndecidableInstances #-}
14+-- Module : Asyncly.AsyncT
15+-- Copyright : (c) 2017 Harendra Kumar
17+-- License : MIT-style
18+-- Maintainer : harendra.kumar@gmail.com
19+-- Stability : experimental
13module Asyncly.AsyncT
23module Asyncly.AsyncT
14 ( AsyncT (..)
24 ( AsyncT (..)
15 , MonadAsync
25 , MonadAsync
@@ -27,11 +37,11 @@ module Asyncly.AsyncT
27 , makeAsync
37 , makeAsync
30− , discardAndThen
40+ , before
32− , thenDiscard
42+ , thereafter
34− , afterFirst
44+ , afterfirst
37 -- internal
47 -- internal
@@ -438,10 +448,11 @@ runAsyncTask forceAsync action = do
438-- action was an infinite loop for example.
448-- action was an infinite loop for example.
440-- | In an 'Alternative' composition, force the action to run asynchronously.
450-- | In an 'Alternative' composition, force the action to run asynchronously.
441−-- The <|> operator implies "can be parallel", whereas async implies "must be
451+-- The @\<|\>@ operator implies "can be parallel", whereas 'async' implies
442−-- parallel". Note that async is not useful and should never be used outside an
452+-- "must be parallel". Note that outside an 'Alternative' composition 'async'
443−-- 'Alternative' composition. Even in an 'Alternative' composition 'async' is
453+-- is not useful and should not be used. Even in an 'Alternative' composition
444−-- not useful in the last action.
454+-- 'async' is not useful as the last action as the last action always runs in
455+-- the current thread.
445async :: MonadAsync m => AsyncT m a -> AsyncT m a
456async :: MonadAsync m => AsyncT m a -> AsyncT m a
446async action = AsyncT $ runAsyncTask True action
457async action = AsyncT $ runAsyncTask True action
@@ -477,9 +488,9 @@ each xs = foldl (<|>) empty $ map return xs
477------------------------------------------------------------------------------
488------------------------------------------------------------------------------
479-- XXX Should n be Word32 instead?
490-- XXX Should n be Word32 instead?
480−-- | Runs a computation under a given thread limit. A limit of 0 means new
491+-- | Runs a computation under a given thread limit. A limit of 0 means all new
481−-- tasks start synchronously in the current thread. New threads are created by
492+-- tasks start synchronously in the current thread unless overridden by
482−-- 'parallel', and APIs that use parallel.
493+-- 'async'.
483threads :: MonadAsync m => Int -> AsyncT m a -> AsyncT m a
494threads :: MonadAsync m => Int -> AsyncT m a -> AsyncT m a
484threads n process = AsyncT $ do
495threads n process = AsyncT $ do
485 oldCr <- gets threadCredit
496 oldCr <- gets threadCredit
@@ -563,44 +574,40 @@ instance (Num a, Monad (AsyncT m)) => Num (AsyncT m a) where
563infixr 1 >>*, *>>, >>|
574infixr 1 >>*, *>>, >>|
565-- XXX This can be moved to utility functions as it is purely app level
576-- XXX This can be moved to utility functions as it is purely app level
566−-- | Run @b@ once, discarding its result when the first task in task set @a@
577+-- | Run @m b@ right after the first event in @m a@ is generated but before it
567−-- has finished. Useful to start a singleton task after the first task has been
578+-- is yielded. The result of @m b@ is discarded.
569−afterFirst :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m a
579+afterfirst :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m a
570−afterFirst ma mb = do
580+afterfirst ma mb = do
571 ref <- liftIO $ newIORef False
581 ref <- liftIO $ newIORef False
573 done <- liftIO $ readIORef ref
583 done <- liftIO $ readIORef ref
574 when (not done) $ (liftIO $ writeIORef ref True) >>* mb
584 when (not done) $ (liftIO $ writeIORef ref True) >>* mb
587+-- | Same as 'afterfirst'.
577(>>|) :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m a
588(>>|) :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m a
578−(>>|) = afterFirst
589+(>>|) = afterfirst
580−-- | Run 'm a' in "isolation" and discard its result, and then run 'm b' and
591+-- | Run @m a@ before running @m b@. The result of @m a@ is discarded.
581−-- return its result. Isolation means that any alternative actions inside 'm
582−-- a' are not continued to 'm b'.
583−discardAndThen :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m b
592+before :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m b
584−discardAndThen ma mb = AsyncT $ do
593+before ma mb = AsyncT $ do
585 _ <- runAsyncT (ma >> mzero)
594 _ <- runAsyncT (ma >> mzero)
586 runAsyncT mb
595 runAsyncT mb
588−-- | Same as 'discardAndThen'.
597+-- | Same as 'before'.
589(*>>) :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m b
598(*>>) :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m b
590−(*>>) = discardAndThen
599+(*>>) = before
592−-- | Run 'm a' and then run 'm b' in "isolation" and return the result of 'm
601+-- | Run @m b@ after running @m a@. The result of @m b@ is discarded.
593−-- a'. Isolation means that any alternative actions inside 'm a' are not
594−-- continued to 'm b' and the results of 'm b' are discarded.
595−thenDiscard :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m a
602+thereafter :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m a
596−thenDiscard ma mb = AsyncT $ do
603+thereafter ma mb = AsyncT $ do
597 a <- runAsyncT ma
604 a <- runAsyncT ma
598 _ <- runAsyncT (mb >> mzero)
605 _ <- runAsyncT (mb >> mzero)
601−-- | Same as 'thenDiscard'.
608+-- | Same as 'thereafter'.
602(>>*) :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m a
609(>>*) :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m a
603−(>>*) = thenDiscard
610+(>>*) = thereafter
605-------------------------------------------------------------------------------
612-------------------------------------------------------------------------------
606-- AsyncT transformer
613-- AsyncT transformer