-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Type classes generalizing the functionality of the 'monad-par' library.
--   
--   The <a>Par</a> monad offers a parallel programming API based on
--   dataflow programming. To use the <a>Par</a> monad, install the
--   <tt>monad-par</tt> package, which includes this package as a
--   dependency.
--   
--   This package is an abstract interface only. It provides a number of
--   type clasess, but not an implementation. The type classes separate
--   different levels of <tt>Par</tt> functionality. See the
--   <a>Control.Monad.Par.Class</a> module for more details.
@package abstract-par
@version 0.3.3


-- | Unsafe operations. NOT part of "Safe Haskell".
--   
--   These are "unsafe" (in the normal, Haskell sense) when used with a
--   "runPar" of type `Par a -&gt; a`. If used with a <tt>runParIO</tt>
--   that stays in the IO monad, then they are simply dangerous.
--   
--   For the purposes of Safe Haskell, any module that imports this module
--   becomes untrustworthy.
module Control.Monad.Par.Unsafe

-- | The class of Par monads that provide unsafe functionality.
class ParUnsafe iv p | p -> iv

-- | Peek at the current contents of an <tt>IVar</tt> in a nonblocking way.
unsafePeek :: ParUnsafe iv p => iv a -> p (Maybe a)

-- | Attempt to put a value into an <tt>IVar</tt>. If successful, return
--   the value put. If something is already there, return it instead.
unsafeTryPut :: ParUnsafe iv p => iv a -> a -> p a

-- | Lift an <a>IO</a> operation into the Par monad.
unsafeParIO :: ParUnsafe iv p => IO a -> p a


-- | This module establishes a class hierarchy that captures the interfaces
--   of <tt>Par</tt> monads. There are two layers: simple futures
--   (<a>ParFuture</a>) and full <tt>IVars</tt> (<a>ParIVar</a>). All
--   <tt>Par</tt> monads are expected to implement the former, some also
--   implement the latter.
--   
--   For more documentation of the programming model, see
--   
--   <ul>
--   <li>The <a>Control.Monad.Par</a> module in the <tt>monad-par</tt>
--   package.</li>
--   <li>The wiki/tutorial
--   (<a>http://www.haskell.org/haskellwiki/Par_Monad:_A_Parallelism_Tutorial</a>)</li>
--   <li>The original paper
--   (<a>http://www.cs.indiana.edu/~rrnewton/papers/haskell2011_monad-par.pdf</a>)</li>
--   <li>Tutorial slides
--   (<a>http://community.haskell.org/~simonmar/slides/CUFP.pdf</a>)</li>
--   <li>Other slides
--   (<a>http://www.cs.ox.ac.uk/ralf.hinze/WG2.8/28/slides/simon.pdf</a>,
--   <a>http://www.cs.indiana.edu/~rrnewton/talks/2011_HaskellSymposium_ParMonad.pdf</a>)</li>
--   </ul>
module Control.Monad.Par.Class

-- | <tt>ParFuture</tt> captures the class of Par monads which support
--   futures. This level of functionality subsumes
--   <tt>par</tt>/<tt>pseq</tt> and is similar to the
--   <a>Control.Parallel.Strategies.Eval</a> monad.
--   
--   A minimal implementation consists of <a>spawn_</a> and <a>get</a>.
--   However, for monads that are also a member of <a>ParIVar</a> it is
--   typical to simply define <a>spawn</a> in terms of <a>fork</a>,
--   <a>new</a>, and <a>put</a>.
class Monad m => ParFuture future m | m -> future where spawn p = spawn_ (do { x <- p; deepseq x (return x) }) spawnP a = spawn (return a)

-- | Create a potentially-parallel computation, and return a <i>future</i>
--   (or <i>promise</i>) that can be used to query the result of the forked
--   computataion.
--   
--   <pre>
--   spawn p = do
--     r &lt;- new
--     fork (p &gt;&gt;= put r)
--     return r
--   </pre>
spawn :: (ParFuture future m, NFData a) => m a -> m (future a)

-- | Like <a>spawn</a>, but the result is only head-strict, not
--   fully-strict.
spawn_ :: ParFuture future m => m a -> m (future a)

-- | Wait for the result of a future, and then return it.
get :: ParFuture future m => future a -> m a

-- | Spawn a pure (rather than monadic) computation. Fully-strict.
--   
--   <pre>
--   spawnP = spawn . return
--   </pre>
spawnP :: (ParFuture future m, NFData a) => a -> m (future a)

-- | <tt>ParIVar</tt> builds on futures by adding full <i>anyone-writes,
--   anyone-reads</i> IVars. These are more expressive but may not be
--   supported by all distributed schedulers.
--   
--   A minimal implementation consists of <a>fork</a>, <a>put_</a>, and
--   <a>new</a>.
class ParFuture ivar m => ParIVar ivar m | m -> ivar where put v a = deepseq a (put_ v a) newFull a = deepseq a (newFull_ a) newFull_ a = do { v <- new; put_ v a; return v }

-- | Forks a computation to happen in parallel. The forked computation may
--   exchange values with other computations using <tt>IVar</tt>s.
fork :: ParIVar ivar m => m () -> m ()

-- | creates a new <tt>IVar</tt>
new :: ParIVar ivar m => m (ivar a)

-- | put a value into a <tt>IVar</tt>. Multiple <a>put</a>s to the same
--   <tt>IVar</tt> are not allowed, and result in a runtime error.
--   
--   <a>put</a> fully evaluates its argument, which therefore must be an
--   instance of <a>NFData</a>. The idea is that this forces the work to
--   happen when we expect it, rather than being passed to the consumer of
--   the <tt>IVar</tt> and performed later, which often results in less
--   parallelism than expected.
--   
--   Sometimes partial strictness is more appropriate: see <a>put_</a>.
put :: (ParIVar ivar m, NFData a) => ivar a -> a -> m ()

-- | like <a>put</a>, but only head-strict rather than fully-strict.
put_ :: ParIVar ivar m => ivar a -> a -> m ()

-- | creates a new <tt>IVar</tt> that contains a value
newFull :: (ParIVar ivar m, NFData a) => a -> m (ivar a)

-- | creates a new <tt>IVar</tt> that contains a value (head-strict only)
newFull_ :: ParIVar ivar m => a -> m (ivar a)

-- | A class of types that can be fully evaluated.
class NFData a
