{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
   This module is an alternative version of "Control.Monad.Par" in
   which the `Par` type provides `IO` operations, by means of `liftIO`.
   The price paid is that only `runParIO` is available, not the pure `runPar`.

   This module uses the same default scheduler as "Control.Monad.Par".
 -}

module Control.Monad.Par.IO
  ( ParIO, IVar, runParIO
    -- And instances!               
  )
  where

import Control.Monad.Par.Scheds.Trace (Par, IVar)
import qualified Control.Monad.Par.Scheds.TraceInternal as Internal

import Control.Monad.Par.Class
import Control.Applicative
import Control.Monad.Trans (liftIO, MonadIO)
import Control.Monad.Fix (MonadFix)

-- | A wrapper around an underlying Par type which allows IO.
newtype ParIO a = ParIO (Par a)
  deriving (forall a b. a -> ParIO b -> ParIO a
forall a b. (a -> b) -> ParIO a -> ParIO b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> ParIO b -> ParIO a
$c<$ :: forall a b. a -> ParIO b -> ParIO a
fmap :: forall a b. (a -> b) -> ParIO a -> ParIO b
$cfmap :: forall a b. (a -> b) -> ParIO a -> ParIO b
Functor, Functor ParIO
forall a. a -> ParIO a
forall a b. ParIO a -> ParIO b -> ParIO a
forall a b. ParIO a -> ParIO b -> ParIO b
forall a b. ParIO (a -> b) -> ParIO a -> ParIO b
forall a b c. (a -> b -> c) -> ParIO a -> ParIO b -> ParIO c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. ParIO a -> ParIO b -> ParIO a
$c<* :: forall a b. ParIO a -> ParIO b -> ParIO a
*> :: forall a b. ParIO a -> ParIO b -> ParIO b
$c*> :: forall a b. ParIO a -> ParIO b -> ParIO b
liftA2 :: forall a b c. (a -> b -> c) -> ParIO a -> ParIO b -> ParIO c
$cliftA2 :: forall a b c. (a -> b -> c) -> ParIO a -> ParIO b -> ParIO c
<*> :: forall a b. ParIO (a -> b) -> ParIO a -> ParIO b
$c<*> :: forall a b. ParIO (a -> b) -> ParIO a -> ParIO b
pure :: forall a. a -> ParIO a
$cpure :: forall a. a -> ParIO a
Applicative, Applicative ParIO
forall a. a -> ParIO a
forall a b. ParIO a -> ParIO b -> ParIO b
forall a b. ParIO a -> (a -> ParIO b) -> ParIO b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> ParIO a
$creturn :: forall a. a -> ParIO a
>> :: forall a b. ParIO a -> ParIO b -> ParIO b
$c>> :: forall a b. ParIO a -> ParIO b -> ParIO b
>>= :: forall a b. ParIO a -> (a -> ParIO b) -> ParIO b
$c>>= :: forall a b. ParIO a -> (a -> ParIO b) -> ParIO b
Monad, ParFuture IVar, ParIVar IVar, Monad ParIO
forall a. (a -> ParIO a) -> ParIO a
forall (m :: * -> *).
Monad m -> (forall a. (a -> m a) -> m a) -> MonadFix m
mfix :: forall a. (a -> ParIO a) -> ParIO a
$cmfix :: forall a. (a -> ParIO a) -> ParIO a
MonadFix)

-- | A run method which allows actual IO to occur on top of the Par
--   monad.  Of course this means that all the normal problems of
--   parallel IO computations are present, including nondeterminism.
--
--   A simple example program:
--
--   >  runParIO (liftIO $ putStrLn "hi" :: ParIO ())
runParIO :: ParIO a -> IO a
runParIO :: forall a. ParIO a -> IO a
runParIO (ParIO Par a
p) = forall a. Par a -> IO a
Internal.runParIO Par a
p

instance MonadIO ParIO where
    liftIO :: forall a. IO a -> ParIO a
liftIO IO a
io = forall a. Par a -> ParIO a
ParIO (forall a. ((a -> Trace) -> Trace) -> Par a
Internal.Par (forall a. IO a -> (a -> Trace) -> Trace
Internal.LiftIO IO a
io))