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

-- | Type classes generalizing the functionality of the 'monad-par' library.
--   
--   The Par monad offers a parallel programming API based on
--   dataflow programming. To use the Par monad, install the
--   monad-par 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 Par functionality. See the
--   Control.Monad.Par.Class module for more details.
@package abstract-par
@version 0.3.3

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

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

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

-- | Like spawn, 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.
--   
--   
--   spawnP = spawn . return
--   
spawnP :: (ParFuture future m, NFData a) => a -> m (future a)

-- | ParIVar builds on futures by adding full anyone-writes,
--   anyone-reads IVars. These are more expressive but may not be
--   supported by all distributed schedulers.
--   
--   A minimal implementation consists of fork, put_, and
--   new.
class ParFuture ivar m => ParIVar (ivar :: Type -> Type) (m :: Type -> Type) | m -> ivar

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

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

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

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

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

-- | creates a new IVar 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

-- | 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 runParIO
--   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 :: Type -> Type) (p :: Type -> Type) | p -> iv

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

-- | Attempt to put a value into an IVar. 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 IO operation into the Par monad.
unsafeParIO :: ParUnsafe iv p => IO a -> p a
