-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Mix concurrent and sequential computation -- @package Concurrential @version 0.4.0.0 -- | 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 m. data Concurrential m t -- | This corresponds to the notion of a common type of monad transformer: -- there is some monad g, and then its associated transformer type f, for -- instance MaybeT = f and Maybe = g If we have an -- --
--   f m a
--   
--   
-- -- then we can get an -- --
--   m (g a)
--   
--   
-- -- 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! -- -- Motivation: Async functions work with IO and only -- IO, but the m parameter of a Concurrential may be -- some other monad which is capable of performing IO, like -- Either String IO for instance. In order to run computations -- in this moand through Async, we need to know how to get a -- hold of an IO. That's what the runner does. type Runner f g = forall a. f a -> IO (g a) -- | A witness of this type proves that g is in some sense compatible with -- IO: we can bind through it. type Joiner g = forall a. g (IO a) -> IO (g a) -- | Run a Concurrential term, realizing the effects of the IO-like terms -- which compose it. runConcurrential :: (Functor f, Applicative f, Monad f) => Joiner f -> Runner m f -> Concurrential m t -> (Async (f t) -> IO (f r)) -> IO (f r) runConcurrentialSimple :: Concurrential IO t -> (Async t -> IO r) -> IO r -- | Create an effect 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 effect 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 -- | Wait for an asynchronous action to complete, and return its value. If -- the asynchronous action threw an exception, then the exception is -- re-thrown by wait. -- --
--   wait = atomically . waitSTM
--   
wait :: Async a -> IO a instance Typeable Choice instance Typeable Concurrential instance Functor Identity instance Applicative m => Monad (Concurrential m) instance Applicative m => Applicative (Concurrential m) instance Functor m => Functor (Concurrential m) instance Functor m => Functor (Choice m) instance Monad Identity instance Applicative Identity