-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A monad for managed values -- -- In Haskell you very often acquire values using the with... -- idiom using functions of type (a -> IO r) -> IO r. This -- idiom forms a Monad, which is a special case of the -- ContT monad (from transformers) or the -- Codensity monad (from kan-extensions). The main -- purpose behind this package is to provide a restricted form of these -- monads specialized to this unusually common case. -- -- The reason this package defines a specialized version of these types -- is to: -- -- @package managed @version 1.0.10 -- | An example Haskell program to copy data from one handle to another -- might look like this: -- --
--   main =
--       withFile "inFile.txt" ReadMode $ \inHandle ->
--           withFile "outFile.txt" WriteMode $ \outHandle ->
--               copy inHandle outHandle
--   
--   -- A hypothetical function that copies data from one handle to another
--   copy :: Handle -> Handle -> IO ()
--   
-- -- withFile is one of many functions that acquire some resource in -- an exception-safe way. These functions take a callback function as an -- argument and they invoke the callback on the resource when it becomes -- available, guaranteeing that the resource is properly disposed if the -- callback throws an exception. -- -- These functions usually have a type that ends with the following -- pattern: -- --
--                      Callback
--   --                -----------
--   withXXX :: ... -> (a -> IO r) -> IO r
--   
-- -- Here are some examples of this pattern from the base -- libraries: -- --
--   withArray      :: Storable a => [a] -> (Ptr a   -> IO r) -> IO r
--   withBuffer     ::          Buffer e -> (Ptr e   -> IO r) -> IO r
--   withCAString   ::            String -> (CString -> IO r) -> IO r
--   withForeignPtr ::      ForeignPtr a -> (Ptr a   -> IO r) -> IO r
--   withMVar       ::            Mvar a -> (a       -> IO r) -> IO r
--   withPool       ::                      (Pool    -> IO r) -> IO r
--   
-- -- Acquiring multiple resources in this way requires nesting callbacks. -- However, you can wrap anything of the form ((a -> IO r) -> -- IO r) in the Managed monad, which translates binds to -- callbacks for you: -- --
--   import Control.Monad.Managed
--   import System.IO
--   
--   inFile :: FilePath -> Managed Handle
--   inFile filePath = managed (withFile filePath ReadMode)
--   
--   outFile :: FilePath -> Managed Handle
--   outFile filePath = managed (withFile filePath WriteMode)
--   
--   main = runManaged $ do
--       inHandle  <- inFile "inFile.txt"
--       outHandle <- outFile "outFile.txt"
--       liftIO (copy inHandle outHandle)
--   
-- -- ... or you can just wrap things inline: -- --
--   main = runManaged $ do
--       inHandle  <- managed (withFile "inFile.txt" ReadMode)
--       outHandle <- managed (withFile "outFile.txt" WriteMode)
--       liftIO (copy inHandle outHandle)
--   
-- -- Additionally, since Managed is a Monad, you can take -- advantage of all your favorite combinators from Control.Monad. -- For example, the withMany function from -- Foreign.Marshal.Utils becomes a trivial wrapper around -- mapM: -- --
--   withMany :: (a -> (b -> IO r) -> IO r) -> [a] -> ([b] -> IO r) -> IO r
--   withMany f = with . mapM (Managed . f)
--   
-- -- Another reason to use Managed is that if you wrap a -- Monoid value in Managed you get back a new -- Monoid: -- --
--   instance Monoid a => Monoid (Managed a)
--   
-- -- This lets you combine managed resources transparently. You can also -- lift operations from some numeric type classes this way, too, such as -- the Num type class. -- -- NOTE: Managed may leak space if used in an infinite loop like -- this example: -- --
--   import Control.Monad
--   import Control.Monad.Managed
--   
--   main = runManaged (forever (liftIO (print 1)))
--   
-- -- If you need to acquire a resource for a long-lived loop, you can -- instead acquire the resource first and run the loop in IO, -- using either of the following two equivalent idioms: -- --
--   with resource (\r -> forever (useThe r))
--   
--   do r <- resource
--      liftIO (forever (useThe r))
--   
module Control.Monad.Managed -- | A managed resource that you acquire using with data Managed a -- | You can embed a Managed action within any Monad that -- implements MonadManaged by using the using function -- -- All instances must obey the following two laws: -- --
--   using (return x) = return x
--   
--   using (m >>= f) = using m >>= \x -> using (f x)
--   
class MonadIO m => MonadManaged m using :: MonadManaged m => Managed a -> m a -- | Build a Managed value managed :: MonadManaged m => (forall r. (a -> IO r) -> IO r) -> m a -- | Like managed but for resource-less operations. managed_ :: MonadManaged m => (forall r. IO r -> IO r) -> m () -- | Defer running an action until exit (via runManaged). -- -- For example, the following code will print "Hello" followed by -- "Goodbye": -- --
--   runManaged $ do
--     defer $ liftIO $ putStrLn "Goodbye"
--     liftIO $ putStrLn "Hello"
--   
defer :: MonadManaged m => IO r -> m () -- | Acquire a Managed value -- -- This is a potentially unsafe function since it allows a resource to -- escape its scope. For example, you might use Managed to safely -- acquire a file handle, like this: -- --
--   import qualified System.IO as IO
--   
--   example :: Managed Handle
--   example = managed (IO.withFile "foo.txt" IO.ReadMode)
--   
-- -- ... and if you never used the with function then you would -- never run the risk of accessing the Handle after the file was -- closed. However, if you use with then you can incorrectly -- access the handle after the handle is closed, like this: -- --
--   bad :: IO ()
--   bad = do
--       handle <- with example return
--       IO.hPutStrLn handle "bar"  -- This will fail because the handle is closed
--   
-- -- ... so only use with if you know what you are doing and you're -- returning a value that is not a resource being managed. with :: Managed a -> (a -> IO r) -> IO r -- | Run a Managed computation, enforcing that no acquired resources -- leak runManaged :: Managed () -> IO () -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. This allows us to run IO -- computations in any monadic stack, so long as it supports these kinds -- of operations (i.e. IO is the base monad for the stack). -- --

Example

-- --
--   import Control.Monad.Trans.State -- from the "transformers" library
--   
--   printState :: Show s => StateT s IO ()
--   printState = do
--     state <- get
--     liftIO $ print state
--   
-- -- Had we omitted liftIO, we would have ended up with -- this error: -- --
--   • Couldn't match type ‘IO’ with ‘StateT s IO’
--    Expected type: StateT s IO ()
--      Actual type: IO ()
--   
-- -- The important part here is the mismatch between StateT s IO -- () and IO (). -- -- Luckily, we know of a function that takes an IO a and -- returns an (m a): liftIO, enabling us to run -- the program and see the expected results: -- --
--   > evalStateT printState "hello"
--   "hello"
--   
--   > evalStateT printState 3
--   3
--   
liftIO :: MonadIO m => IO a -> m a instance Control.Monad.Managed.MonadManaged Control.Monad.Managed.Managed instance Control.Monad.Managed.MonadManaged m => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.Cont.ContT r m) instance Control.Monad.Managed.MonadManaged m => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.Except.ExceptT e m) instance Control.Monad.Managed.MonadManaged m => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.Identity.IdentityT m) instance Control.Monad.Managed.MonadManaged m => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.Maybe.MaybeT m) instance Control.Monad.Managed.MonadManaged m => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.Reader.ReaderT r m) instance (GHC.Base.Monoid w, Control.Monad.Managed.MonadManaged m) => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.RWS.Lazy.RWST r w s m) instance (GHC.Base.Monoid w, Control.Monad.Managed.MonadManaged m) => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.RWS.Strict.RWST r w s m) instance Control.Monad.Managed.MonadManaged m => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.State.Strict.StateT s m) instance Control.Monad.Managed.MonadManaged m => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.State.Lazy.StateT s m) instance (GHC.Base.Monoid w, Control.Monad.Managed.MonadManaged m) => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.Writer.Strict.WriterT w m) instance (GHC.Base.Monoid w, Control.Monad.Managed.MonadManaged m) => Control.Monad.Managed.MonadManaged (Control.Monad.Trans.Writer.Lazy.WriterT w m) instance GHC.Base.Functor Control.Monad.Managed.Managed instance GHC.Base.Applicative Control.Monad.Managed.Managed instance GHC.Base.Monad Control.Monad.Managed.Managed instance Control.Monad.IO.Class.MonadIO Control.Monad.Managed.Managed instance Control.Monad.Fail.MonadFail Control.Monad.Managed.Managed instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Control.Monad.Managed.Managed a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Control.Monad.Managed.Managed a) instance GHC.Num.Num a => GHC.Num.Num (Control.Monad.Managed.Managed a) instance GHC.Real.Fractional a => GHC.Real.Fractional (Control.Monad.Managed.Managed a) instance GHC.Float.Floating a => GHC.Float.Floating (Control.Monad.Managed.Managed a) -- | This module is a safer subset of Control.Monad.Managed that -- only lets you unwrap the Managed type using runManaged. -- This enforces that you never leak acquired resources from a -- Managed computation. -- -- In general, you should strive to propagate the Managed type as -- much as possible and use runManaged when you are done with -- acquired resources. However, there are legitimate circumstances where -- you want to return a value other than acquired resource from the -- bracketed computation, which requires using with. -- -- This module is not the default because you can also use the -- Managed type for callback-based code that is completely -- unrelated to resources. module Control.Monad.Managed.Safe -- | A managed resource that you acquire using with data Managed a -- | You can embed a Managed action within any Monad that -- implements MonadManaged by using the using function -- -- All instances must obey the following two laws: -- --
--   using (return x) = return x
--   
--   using (m >>= f) = using m >>= \x -> using (f x)
--   
class MonadIO m => MonadManaged m using :: MonadManaged m => Managed a -> m a -- | Build a Managed value managed :: MonadManaged m => (forall r. (a -> IO r) -> IO r) -> m a -- | Like managed but for resource-less operations. managed_ :: MonadManaged m => (forall r. IO r -> IO r) -> m () -- | Defer running an action until exit (via runManaged). -- -- For example, the following code will print "Hello" followed by -- "Goodbye": -- --
--   runManaged $ do
--     defer $ liftIO $ putStrLn "Goodbye"
--     liftIO $ putStrLn "Hello"
--   
defer :: MonadManaged m => IO r -> m () -- | Run a Managed computation, enforcing that no acquired resources -- leak runManaged :: Managed () -> IO () -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. This allows us to run IO -- computations in any monadic stack, so long as it supports these kinds -- of operations (i.e. IO is the base monad for the stack). -- --

Example

-- --
--   import Control.Monad.Trans.State -- from the "transformers" library
--   
--   printState :: Show s => StateT s IO ()
--   printState = do
--     state <- get
--     liftIO $ print state
--   
-- -- Had we omitted liftIO, we would have ended up with -- this error: -- --
--   • Couldn't match type ‘IO’ with ‘StateT s IO’
--    Expected type: StateT s IO ()
--      Actual type: IO ()
--   
-- -- The important part here is the mismatch between StateT s IO -- () and IO (). -- -- Luckily, we know of a function that takes an IO a and -- returns an (m a): liftIO, enabling us to run -- the program and see the expected results: -- --
--   > evalStateT printState "hello"
--   "hello"
--   
--   > evalStateT printState 3
--   3
--   
liftIO :: MonadIO m => IO a -> m a