-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | An implementation of forkIO for monad stacks. -- -- This module defines a more generic version of Control.Concurrent's -- forkIO, which can directly run some complex monadic actions as well as -- plain IO actions. @package forkable-monad @version 0.1 -- | This module defines a generic version of Control.Concurrent's -- forkIO, which can directly run some complex monadic actions as -- well as plain IO actions. -- -- Control.Concurrent's forkIO accepts an IO -- computation only, and requires the caller to reconstruct the full -- monadic stack by hand in the new thread. In contrast, this module's -- forkIO runs a computation in the same monad as the parent -- thread, transparently transplanting the monad stack to the new thread. -- -- For example, the following code which uses -- Control.Concurrent's forkIO: -- --
--   type MyMonad = ReaderT Int (StateT String IO)
--   
--   forkAndDo :: MyMonad ThreadId
--   forkAndDo = do
--       r <- ask
--       s <- lift get
--       liftIO $ forkIO $ (runStateT (runReaderT forkedDo r) s >> return ())
--   
--   forkedDo :: MyMonad ()
--   forkedDo = liftIO $ putStrLn "forkedDo running"
--   
-- -- can be reexpressed with this module's forkIO as: -- --
--   type MyMonad = ReaderT Int (StateT String IO)
--   
--   forkAndDo :: MyMonad ThreadId
--   forkAndDo = forkIO forkedDo
--   
--   forkedDo :: MyMonad ()
--   forkedDo = liftIO $ putStrLn "forkedDo running"
--   
-- -- forkIO can operate on any monad that is an instance of -- ForkableMonad. ForkableMonad instances are defined for -- ReaderT and StateT, as well as IO. Here is the -- precise meaning of "transplant" for each of these: -- -- -- -- Other standard transformers (notably WriterT, ErrorT -- and RWST) do not have an instance defined, because those -- instances can only be defined through data loss. -- -- For example, the current output of a Writer cannot be -- accessed from within the monad, so the best that can be done is to -- create a new pristine Writer state for the new thread, and to -- discard all data written in that thread when the thread terminates. -- -- If you want to use forkIO on a monad stack that includes one of -- these lossy monads, you will need to define the ForkableMonad -- instances yourself. The same goes for any custom monads you may have -- in the stack. -- -- This module reexports Control.Concurrent overlayed with the -- generic forkIO, so you can simply change your import from -- Control.Concurrent to Control.Concurrent.Forkable to -- use this module's forkIO in your existing concurrent code. module Control.Concurrent.Forkable class (MonadIO m) => ForkableMonad m forkIO :: (ForkableMonad m) => m a -> m ThreadId instance (ForkableMonad m) => ForkableMonad (StateT s m) instance (ForkableMonad m) => ForkableMonad (ReaderT r m) instance ForkableMonad IO