-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Mix concurrent and sequential computation -- @package Concurrential @version 0.2.1.0 module Control.Concurrent.Except data ExceptT e m a ExceptT :: m (Either e a) -> ExceptT e m a runExceptT :: ExceptT e m a -> m (Either e a) injectE :: Applicative m => Either e a -> ExceptT e m a throwE :: Applicative m => e -> ExceptT e m a catchE :: Monad m => ExceptT e m a -> (e -> ExceptT e' m a) -> ExceptT e' m a instance Typeable ExceptT instance Monad m => Monad (ExceptT e m) instance Applicative m => Applicative (ExceptT e m) instance Functor m => Functor (ExceptT e m) -- | The functions sequentially and concurrently inject -- IO terms into the Concurrential monad. This monad's -- Applicative instance will exploit as much concurrency as possible, -- much like the Concurrently monad from async, such that all -- sequentially terms will be run in the order in which they -- would have been run had they been typical IOs. module Control.Concurrent.Concurrential -- | Description of computation which is composed of sequential and -- concurrent parts in some monad. data Concurrential m t -- | A witness of this type proves that g is in some sense compatible with -- IO: we can bind through it. TBD would it suffice to give the simpler -- type forall a . g (IO a) -> IO (g a) ? type Retractor g = forall a. g (IO (g a)) -> IO (g a) -- | This corresponds to the notion of a monad transformer; there is some -- monad g, and then its associated transformer f. If you have an -- -- f m a -- -- then you can get an -- -- m (g a) -- -- just by the definition of what it means to be a monad transformer. -- Here we're interested in the special case where we can achieve IO (g -- a). This does not mean we have to be dealing with an f IO a, it could -- mean that the IO is buried deeper in the transformer stack! type Injector f g = forall a. f a -> IO (g a) -- | Run a Concurrential term, realizing the effects of the IO-like terms -- which compose it. runConcurrential :: (Functor m, Applicative m, Monad m) => Retractor m -> Injector f m -> Concurrential f t -> IO (m t) runConcurrentialSimple :: Concurrential IO t -> IO t -- | Create an IO which must be run sequentially. If a sequentially -- io appears in a Concurrential t term then it will always -- be run to completion before any later sequential part of the term is -- run. Consider the following terms: -- --
--   a = someConcurrential *> sequentially io *> someOtherConcurrential
--   b = someConcurrential *> concurrently io *> someOtherConcurrential
--   c = someConcurrential *> sequentially io *> concurrently otherIo
--   
--   
-- -- When running the term a, we are guaranteed that io -- is completed before any sequential part of -- someOtherConcurrential is begun, but when running the term -- b, this is not the case; io may be interleaved with -- or even run after any part of someOtherConcurrential. The -- term c highlights an important point: concurrently -- otherIo may be run before, during or after sequentially -- io! The ordering through applicative combinators is guaranteed -- only among sequential terms. sequentially :: m t -> Concurrential m t -- | Create an IO which is run concurrently where possible, i.e. whenever -- it combined applicatively with other terms. For instance: -- --
--   a = concurrently io *> someConcurrential
--   b = concurrently io >> someConcurrential
--   
--   
-- -- When running the term a, the IO term io will be run -- concurrently with someConcurrential, but not so in -- b, because monadic composition has been used. concurrently :: m t -> Concurrential m t instance Typeable Choice instance Typeable Concurrential instance Applicative m => Monad (Concurrential m) instance Applicative m => Applicative (Concurrential m) instance Functor m => Functor (Concurrential m) instance Functor m => Functor (Choice m) module Control.Concurrent.Concurrential.Safely -- | Make an arbitrary IO suitable for use with sequentially or -- concurrently so as to produce a term that can be run by -- runSafely: -- -- let a = concurrently . safely $ dangerousComputation1 b = concurrently -- . safely $ dangerousComputation2 in runSafely $ a *> b safely :: IO a -> ExceptT SomeException IO a -- | Run a term such that computation is halted as soon as an exception is -- encountered, but any pending threads are waited on. The first -- exception to be thown (in term-order, not necessarily temporal order) -- is given as Left, and a Right is given if no exception is encountered. runSafely :: Concurrential (ExceptT SomeException IO) a -> IO (Either SomeException a)