Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Verification monad
Verification monad
The verification monad is similar to ResourceT
in intent, in that we can
register handlers to be run to release resources. Unlike ResourceT
,
however, we maintain _two_ handlers: a cleanup handler which is run whether
or not verification succeeds, and a finalisation handler which is run only if
verification succeeds.
- Cleanup handlers are registered using
acquire
, and are guaranteed to run just before the computation terminates (after the finalisation handler). - The finalisation handlers are run only when verification succeeds, and can
be registered with
ifVerified
. Finalisation can be used for instance to update the local cache (which should only happen if verification is successful).
acquire :: IO a -> (a -> IO ()) -> Verify a Source #
Acquire a resource and register the corresponding cleanup handler
NOTE: Resource acquisition happens with exceptions masked. If it is important that the resource acquistion can be timed out (or receive other kinds of asynchronous exceptions), you will need to use an interruptible operation. See http://www.well-typed.com/blog/2014/08/asynchronous-exceptions/ for details.
ifVerified :: IO () -> Verify () Source #
Register an action to be run only if verification succeeds
Specific resources
Create a short-lived temporary file
Creates the directory where the temp file should live if it does not exist.
Re-exports
liftIO :: MonadIO m => IO a -> m a #
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
, we would have ended up with this error:liftIO
• 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
and returns an IO
a(m a)
:
,
enabling us to run the program and see the expected results:liftIO
> evalStateT printState "hello" "hello" > evalStateT printState 3 3