    {-# 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 -> b) -> ParIO a -> ParIO b)
    -> (forall a b. a -> ParIO b -> ParIO a) -> Functor ParIO
    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
    $cfmap :: forall a b. (a -> b) -> ParIO a -> ParIO b
    fmap :: forall a b. (a -> b) -> ParIO a -> ParIO b
    $c<$ :: forall a b. a -> ParIO b -> ParIO a
    <$ :: forall a b. a -> ParIO b -> ParIO a
    Functor, Functor ParIO
    Functor ParIO
    -> (forall a. a -> ParIO a)
    -> (forall a b. ParIO (a -> b) -> ParIO a -> ParIO b)
    -> (forall a b c. (a -> b -> c) -> ParIO a -> ParIO b -> ParIO c)
    -> (forall a b. ParIO a -> ParIO b -> ParIO b)
    -> (forall a b. ParIO a -> ParIO b -> ParIO a)
    -> Applicative 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
    $cpure :: forall a. a -> ParIO a
    pure :: forall a. a -> ParIO a
    $c<*> :: forall a b. ParIO (a -> b) -> ParIO a -> ParIO b
    <*> :: forall a b. ParIO (a -> b) -> ParIO a -> ParIO b
    $cliftA2 :: forall a b c. (a -> b -> c) -> ParIO a -> ParIO b -> ParIO c
    liftA2 :: forall a b c. (a -> b -> c) -> ParIO a -> ParIO b -> ParIO c
    $c*> :: forall a b. ParIO a -> ParIO b -> ParIO b
    *> :: forall a b. ParIO a -> ParIO b -> ParIO b
    $c<* :: forall a b. ParIO a -> ParIO b -> ParIO a
    <* :: forall a b. ParIO a -> ParIO b -> ParIO a
    Applicative, Applicative ParIO
    Applicative ParIO
    -> (forall a b. ParIO a -> (a -> ParIO b) -> ParIO b)
    -> (forall a b. ParIO a -> ParIO b -> ParIO b)
    -> (forall a. a -> ParIO a)
    -> Monad 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
    $c>>= :: forall a b. ParIO a -> (a -> ParIO b) -> ParIO b
    >>= :: forall a b. ParIO a -> (a -> ParIO b) -> ParIO b
    $c>> :: forall a b. ParIO a -> ParIO b -> ParIO b
    >> :: forall a b. ParIO a -> ParIO b -> ParIO b
    $creturn :: forall a. a -> ParIO a
    return :: forall a. a -> ParIO a
    Monad, ParFuture IVar, ParIVar IVar, Monad ParIO
    Monad ParIO
    -> (forall a. (a -> ParIO a) -> ParIO a) -> MonadFix ParIO
    forall a. (a -> ParIO a) -> ParIO a
    forall (m :: * -> *).
    Monad m -> (forall a. (a -> m a) -> m a) -> MonadFix m
    $cmfix :: forall a. (a -> ParIO a) -> ParIO a
    mfix :: 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) = Par a -> IO a
    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 = Par a -> ParIO a
    forall a. Par a -> ParIO a
    ParIO (((a -> Trace) -> Trace) -> Par a
    forall a. ((a -> Trace) -> Trace) -> Par a
    Internal.Par (IO a -> (a -> Trace) -> Trace
    forall a. IO a -> (a -> Trace) -> Trace
    Internal.LiftIO IO a
    io))