{-# LANGUAGE CPP
, UnicodeSyntax
, NoImplicitPrelude
, ExistentialQuantification
, FlexibleContexts
#-}#if MIN_VERSION_base(4,3,0){-# LANGUAGE RankNTypes #-}-- for mask#endif#if __GLASGOW_HASKELL__ >= 702{-# LANGUAGE Trustworthy #-}#endif{- |
Module : Control.Exception.Lifted
Copyright : Bas van Dijk, Anders Kaseorg
License : BSD-style
Maintainer : Bas van Dijk <v.dijk.bas@gmail.com>
Stability : experimental
Portability : non-portable (extended exceptions)
This is a wrapped version of "Control.Exception" with types generalized
from 'IO' to all monads in either 'MonadBase' or 'MonadBaseControl'.
-}moduleControl.Exception.Lifted(moduleControl.Exception-- * Throwing exceptions,throwIO,ioError,throwTo-- * Catching exceptions-- ** The @catch@ functions,catch,catches,Handler(..),catchJust-- ** The @handle@ functions,handle,handleJust-- ** The @try@ functions,try,tryJust-- ** The @evaluate@ function,evaluate-- * Asynchronous Exceptions-- ** Asynchronous exception control-- |The following functions allow a thread to control delivery of-- asynchronous exceptions during a critical region.#if MIN_VERSION_base(4,3,0),mask,mask_,uninterruptibleMask,uninterruptibleMask_,getMaskingState#if MIN_VERSION_base(4,4,0),allowInterrupt#endif#else,block,unblock#endif#if !MIN_VERSION_base(4,4,0),blocked#endif-- * Brackets,bracket,bracket_,bracketOnError-- * Utilities,finally,onException)where---------------------------------------------------------------------------------- Imports---------------------------------------------------------------------------------- from base:importData.Function(($))importData.Either(Either(Left,Right),either)importData.Maybe(Maybe)importControl.Monad(Monad,(>>=),return,liftM)importSystem.IO.Error(IOError)importSystem.IO(IO)#if __GLASGOW_HASKELL__ < 700importControl.Monad(fail)#endifimportControl.Exceptionhiding(throwIO,ioError,throwTo,catch,catches,Handler(..),catchJust,handle,handleJust,try,tryJust,evaluate#if MIN_VERSION_base(4,3,0),mask,mask_,uninterruptibleMask,uninterruptibleMask_,getMaskingState#if MIN_VERSION_base(4,4,0),allowInterrupt#endif#else,block,unblock#endif#if !MIN_VERSION_base(4,4,0),blocked#endif,bracket,bracket_,bracketOnError,finally,onException)importqualifiedControl.ExceptionasEimportqualifiedControl.ConcurrentasCimportControl.Concurrent(ThreadId)#if !MIN_VERSION_base(4,4,0)importData.Bool(Bool)#endif-- from base-unicode-symbols:importData.Function.Unicode((∘))-- from transformers-base:importControl.Monad.Base(MonadBase,liftBase)-- from monad-control:importControl.Monad.Trans.Control(MonadBaseControl,StM,liftBaseWith,restoreM,control,liftBaseOp_)#if MIN_VERSION_base(4,3,0) || defined (__HADDOCK__)importControl.Monad.Trans.Control(liftBaseOp)#endif#include "inlinable.h"---------------------------------------------------------------------------------- * Throwing exceptions---------------------------------------------------------------------------------- |Generalized version of 'E.throwIO'.throwIO∷(MonadBaseIOm,Exceptione)⇒e→mathrowIO=liftBase∘E.throwIO{-# INLINABLE throwIO #-}-- |Generalized version of 'E.ioError'.ioError∷MonadBaseIOm⇒IOError→maioError=liftBase∘E.ioError{-# INLINABLE ioError #-}-- | Generalized version of 'C.throwTo'.throwTo∷(MonadBaseIOm,Exceptione)⇒ThreadId→e→m()throwTotide=liftBase$C.throwTotide{-# INLINABLE throwTo #-}---------------------------------------------------------------------------------- * Catching exceptions---------------------------------------------------------------------------------- |Generalized version of 'E.catch'.---- Note, when the given computation throws an exception any monadic-- side effects in @m@ will be discarded.catch∷(MonadBaseControlIOm,Exceptione)⇒ma-- ^ The computation to run→(e→ma)-- ^ Handler to invoke if an exception is raised→macatchahandler=control$\runInIO→E.catch(runInIOa)(\e→runInIO$handlere){-# INLINABLE catch #-}-- |Generalized version of 'E.catches'.---- Note, when the given computation throws an exception any monadic-- side effects in @m@ will be discarded.catches∷MonadBaseControlIOm⇒ma→[Handlerma]→macatchesahandlers=control$\runInIO→E.catches(runInIOa)[E.Handler$\e→runInIO$handlere|Handlerhandler←handlers]{-# INLINABLE catches #-}-- |Generalized version of 'E.Handler'.dataHandlerma=∀e.Exceptione⇒Handler(e→ma)-- |Generalized version of 'E.catchJust'.---- Note, when the given computation throws an exception any monadic-- side effects in @m@ will be discarded.catchJust∷(MonadBaseControlIOm,Exceptione)⇒(e→Maybeb)-- ^ Predicate to select exceptions→ma-- ^ Computation to run→(b→ma)-- ^ Handler→macatchJustpahandler=control$\runInIO→E.catchJustp(runInIOa)(\e→runInIO(handlere)){-# INLINABLE catchJust #-}---------------------------------------------------------------------------------- ** The @handle@ functions---------------------------------------------------------------------------------- |Generalized version of 'E.handle'.---- Note, when the given computation throws an exception any monadic-- side effects in @m@ will be discarded.handle∷(MonadBaseControlIOm,Exceptione)⇒(e→ma)→ma→mahandlehandlera=control$\runInIO→E.handle(\e→runInIO(handlere))(runInIOa){-# INLINABLE handle #-}-- |Generalized version of 'E.handleJust'.---- Note, when the given computation throws an exception any monadic-- side effects in @m@ will be discarded.handleJust∷(MonadBaseControlIOm,Exceptione)⇒(e→Maybeb)→(b→ma)→ma→mahandleJustphandlera=control$\runInIO→E.handleJustp(\e→runInIO(handlere))(runInIOa){-# INLINABLE handleJust #-}---------------------------------------------------------------------------------- ** The @try@ functions--------------------------------------------------------------------------------sequenceEither∷MonadBaseControlIOm⇒Eithere(StMma)→m(Eitherea)sequenceEither=either(return∘Left)(liftMRight∘restoreM){-# INLINE sequenceEither #-}-- |Generalized version of 'E.try'.---- Note, when the given computation throws an exception any monadic-- side effects in @m@ will be discarded.try∷(MonadBaseControlIOm,Exceptione)⇒ma→m(Eitherea)trym=liftBaseWith(\runInIO→E.try(runInIOm))>>=sequenceEither{-# INLINABLE try #-}-- |Generalized version of 'E.tryJust'.---- Note, when the given computation throws an exception any monadic-- side effects in @m@ will be discarded.tryJust∷(MonadBaseControlIOm,Exceptione)⇒(e→Maybeb)→ma→m(Eitherba)tryJustpm=liftBaseWith(\runInIO→E.tryJustp(runInIOm))>>=sequenceEither{-# INLINABLE tryJust #-}---------------------------------------------------------------------------------- ** The @evaluate@ function---------------------------------------------------------------------------------- |Generalized version of 'E.evaluate'.evaluate∷MonadBaseIOm⇒a→maevaluate=liftBase∘E.evaluate{-# INLINABLE evaluate #-}---------------------------------------------------------------------------------- ** Asynchronous exception control--------------------------------------------------------------------------------#if MIN_VERSION_base(4,3,0)-- |Generalized version of 'E.mask'.mask∷MonadBaseControlIOm⇒((∀a.ma→ma)→mb)→mbmask=liftBaseOpE.mask∘liftRestore{-# INLINABLE mask #-}liftRestore∷MonadBaseControlIOm⇒((∀a.ma→ma)→b)→((∀a.IOa→IOa)→b)liftRestorefr=f$liftBaseOp_r{-# INLINE liftRestore #-}-- |Generalized version of 'E.mask_'.mask_∷MonadBaseControlIOm⇒ma→mamask_=liftBaseOp_E.mask_{-# INLINABLE mask_ #-}-- |Generalized version of 'E.uninterruptibleMask'.uninterruptibleMask∷MonadBaseControlIOm⇒((∀a.ma→ma)→mb)→mbuninterruptibleMask=liftBaseOpE.uninterruptibleMask∘liftRestore{-# INLINABLE uninterruptibleMask #-}-- |Generalized version of 'E.uninterruptibleMask_'.uninterruptibleMask_∷MonadBaseControlIOm⇒ma→mauninterruptibleMask_=liftBaseOp_E.uninterruptibleMask_{-# INLINABLE uninterruptibleMask_ #-}-- |Generalized version of 'E.getMaskingState'.getMaskingState∷MonadBaseIOm⇒mMaskingStategetMaskingState=liftBaseE.getMaskingState{-# INLINABLE getMaskingState #-}#if MIN_VERSION_base(4,4,0)-- |Generalized version of 'E.allowInterrupt'.allowInterrupt∷MonadBaseIOm⇒m()allowInterrupt=liftBaseE.allowInterrupt{-# INLINABLE allowInterrupt #-}#endif#else-- |Generalized version of 'E.block'.block∷MonadBaseControlIOm⇒ma→mablock=liftBaseOp_E.block{-# INLINABLE block #-}-- |Generalized version of 'E.unblock'.unblock∷MonadBaseControlIOm⇒ma→maunblock=liftBaseOp_E.unblock{-# INLINABLE unblock #-}#endif#if !MIN_VERSION_base(4,4,0)-- | Generalized version of 'E.blocked'.-- returns @True@ if asynchronous exceptions are blocked in the-- current thread.blocked∷MonadBaseIOm⇒mBoolblocked=liftBaseE.blocked{-# INLINABLE blocked #-}#endif---------------------------------------------------------------------------------- * Brackets---------------------------------------------------------------------------------- |Generalized version of 'E.bracket'.---- Note:---- * When the \"acquire\" or \"release\" computations throw exceptions-- any monadic side effects in @m@ will be discarded.---- * When the \"in-between\" computation throws an exception any-- monadic side effects in @m@ produced by that computation will be-- discarded but the side effects of the \"acquire\" or \"release\"-- computations will be retained.---- * Also, any monadic side effects in @m@ of the \"release\"-- computation will be discarded; it is run only for its side-- effects in @IO@.---- Note that when your @acquire@ and @release@ computations are of type 'IO'-- it will be more efficient to write:---- @'liftBaseOp' ('E.bracket' acquire release)@bracket∷MonadBaseControlIOm⇒ma-- ^ computation to run first (\"acquire resource\")→(a→mb)-- ^ computation to run last (\"release resource\")→(a→mc)-- ^ computation to run in-between→mcbracketbeforeafterthing=control$\runInIO→E.bracket(runInIObefore)(\st→runInIO$restoreMst>>=after)(\st→runInIO$restoreMst>>=thing){-# INLINABLE bracket #-}-- |Generalized version of 'E.bracket_'.---- Note any monadic side effects in @m@ of /both/ the \"acquire\" and-- \"release\" computations will be discarded. To keep the monadic-- side effects of the \"acquire\" computation, use 'bracket' with-- constant functions instead.---- Note that when your @acquire@ and @release@ computations are of type 'IO'-- it will be more efficient to write:---- @'liftBaseOp_' ('E.bracket_' acquire release)@bracket_∷MonadBaseControlIOm⇒ma-- ^ computation to run first (\"acquire resource\")→mb-- ^ computation to run last (\"release resource\")→mc-- ^ computation to run in-between→mcbracket_beforeafterthing=control$\runInIO→E.bracket_(runInIObefore)(runInIOafter)(runInIOthing){-# INLINABLE bracket_ #-}-- |Generalized version of 'E.bracketOnError'.---- Note:---- * When the \"acquire\" or \"release\" computations throw exceptions-- any monadic side effects in @m@ will be discarded.---- * When the \"in-between\" computation throws an exception any-- monadic side effects in @m@ produced by that computation will be-- discarded but the side effects of the \"acquire\" computation-- will be retained.---- * Also, any monadic side effects in @m@ of the \"release\"-- computation will be discarded; it is run only for its side-- effects in @IO@.---- Note that when your @acquire@ and @release@ computations are of-- type 'IO' it will be more efficient to write:---- @'liftBaseOp' ('E.bracketOnError' acquire release)@bracketOnError∷MonadBaseControlIOm⇒ma-- ^ computation to run first (\"acquire resource\")→(a→mb)-- ^ computation to run last (\"release resource\")→(a→mc)-- ^ computation to run in-between→mcbracketOnErrorbeforeafterthing=control$\runInIO→E.bracketOnError(runInIObefore)(\st→runInIO$restoreMst>>=after)(\st→runInIO$restoreMst>>=thing){-# INLINABLE bracketOnError #-}---------------------------------------------------------------------------------- * Utilities---------------------------------------------------------------------------------- |Generalized version of 'E.finally'.---- Note, any monadic side effects in @m@ of the \"afterward\"-- computation will be discarded.finally∷MonadBaseControlIOm⇒ma-- ^ computation to run first→mb-- ^ computation to run afterward (even if an exception was raised)→mafinallyasequel=control$\runInIO→E.finally(runInIOa)(runInIOsequel){-# INLINABLE finally #-}-- |Generalized version of 'E.onException'.---- Note, any monadic side effects in @m@ of the \"afterward\"-- computation will be discarded.onException∷MonadBaseControlIOm⇒ma→mb→maonExceptionmwhat=control$\runInIO→E.onException(runInIOm)(runInIOwhat){-# INLINABLE onException #-}