lens-4.19: Lenses, Folds and Traversals

Copyright(C) 2012-16 Edward Kmett
LicenseBSD-style (see the file LICENSE)
MaintainerEdward Kmett <ekmett@gmail.com>
Stabilityprovisional
PortabilityControl.Exception
Safe HaskellTrustworthy
LanguageHaskell2010

Control.Exception.Lens

Contents

Description

Control.Exception provides an example of a large open hierarchy that we can model with prisms and isomorphisms.

Additional combinators for working with IOException results can be found in System.IO.Error.Lens.

The combinators in this module have been generalized to work with MonadCatch instead of just IO. This enables them to be used more easily in Monad transformer stacks.

Synopsis

Handling

catching :: MonadCatch m => Getting (First a) SomeException a -> m r -> (a -> m r) -> m r Source #

Catch exceptions that match a given ReifiedPrism (or any ReifiedFold, really).

>>> catching _AssertionFailed (assert False (return "uncaught")) $ \ _ -> return "caught"
"caught"
catching :: MonadCatch m => Prism' SomeException a     -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => Lens' SomeException a      -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => Traversal' SomeException a -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => Iso' SomeException a       -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => ReifiedGetter SomeException a     -> m r -> (a -> m r) -> m r
catching :: MonadCatch m => ReifiedFold SomeException a       -> m r -> (a -> m r) -> m r

catching_ :: MonadCatch m => Getting (First a) SomeException a -> m r -> m r -> m r Source #

Catch exceptions that match a given ReifiedPrism (or any ReifiedGetter), discarding the information about the match. This is particularly useful when you have a Prism' e () where the result of the ReifiedPrism or ReifiedFold isn't particularly valuable, just the fact that it matches.

>>> catching_ _AssertionFailed (assert False (return "uncaught")) $ return "caught"
"caught"
catching_ :: MonadCatch m => Prism' SomeException a     -> m r -> m r -> m r
catching_ :: MonadCatch m => Lens' SomeException a      -> m r -> m r -> m r
catching_ :: MonadCatch m => Traversal' SomeException a -> m r -> m r -> m r
catching_ :: MonadCatch m => Iso' SomeException a       -> m r -> m r -> m r
catching_ :: MonadCatch m => ReifiedGetter SomeException a     -> m r -> m r -> m r
catching_ :: MonadCatch m => ReifiedFold SomeException a       -> m r -> m r -> m r

handling :: MonadCatch m => Getting (First a) SomeException a -> (a -> m r) -> m r -> m r Source #

A version of catching with the arguments swapped around; useful in situations where the code for the handler is shorter.

>>> handling _NonTermination (\_ -> return "caught") $ throwIO NonTermination
"caught"
handling :: MonadCatch m => Prism' SomeException a     -> (a -> m r) -> m r -> m r
handling :: MonadCatch m => Lens' SomeException a      -> (a -> m r) -> m r -> m r
handling :: MonadCatch m => Traversal' SomeException a -> (a -> m r) -> m r -> m r
handling :: MonadCatch m => Iso' SomeException a       -> (a -> m r) -> m r -> m r
handling :: MonadCatch m => ReifiedFold SomeException a       -> (a -> m r) -> m r -> m r
handling :: MonadCatch m => ReifiedGetter SomeException a     -> (a -> m r) -> m r -> m r

handling_ :: MonadCatch m => Getting (First a) SomeException a -> m r -> m r -> m r Source #

A version of catching_ with the arguments swapped around; useful in situations where the code for the handler is shorter.

>>> handling_ _NonTermination (return "caught") $ throwIO NonTermination
"caught"
handling_ :: MonadCatch m => Prism' SomeException a     -> m r -> m r -> m r
handling_ :: MonadCatch m => Lens' SomeException a      -> m r -> m r -> m r
handling_ :: MonadCatch m => Traversal' SomeException a -> m r -> m r -> m r
handling_ :: MonadCatch m => Iso' SomeException a       -> m r -> m r -> m r
handling_ :: MonadCatch m => ReifiedGetter SomeException a     -> m r -> m r -> m r
handling_ :: MonadCatch m => ReifiedFold SomeException a       -> m r -> m r -> m r

Trying

trying :: MonadCatch m => Getting (First a) SomeException a -> m r -> m (Either a r) Source #

A variant of try that takes a ReifiedPrism (or any ReifiedFold) to select which exceptions are caught (c.f. tryJust, catchJust). If the Exception does not match the predicate, it is re-thrown.

trying :: MonadCatch m => Prism'     SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => Lens'      SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => Traversal' SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => Iso'       SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => ReifiedGetter     SomeException a -> m r -> m (Either a r)
trying :: MonadCatch m => ReifiedFold       SomeException a -> m r -> m (Either a r)

trying_ :: MonadCatch m => Getting (First a) SomeException a -> m r -> m (Maybe r) Source #

A version of trying that discards the specific exception thrown.

trying_ :: MonadCatch m => Prism'     SomeException a -> m r -> m (Maybe r)
trying_ :: MonadCatch m => Lens'      SomeException a -> m r -> m (Maybe r)
trying_ :: MonadCatch m => Traversal' SomeException a -> m r -> m (Maybe r)
trying_ :: MonadCatch m => Iso'       SomeException a -> m r -> m (Maybe r)
trying_ :: MonadCatch m => ReifiedGetter     SomeException a -> m r -> m (Maybe r)
trying_ :: MonadCatch m => ReifiedFold       SomeException a -> m r -> m (Maybe r)

Throwing

throwing :: AReview SomeException b -> b -> r Source #

Throw an Exception described by a ReifiedPrism. Exceptions may be thrown from purely functional code, but may only be caught within the IO Monad.

throwing l ≡ reviews l throw
throwing :: Prism' SomeException t -> t -> r
throwing :: Iso' SomeException t   -> t -> r

throwing_ :: AReview SomeException () -> m x Source #

Similar to throwing but specialised for the common case of error constructors with no arguments.

data MyError = Foo | Bar
makePrisms ''MyError
throwing_ _Foo :: MonadError MyError m => m a

throwingM :: MonadThrow m => AReview SomeException b -> b -> m r Source #

A variant of throwing that can only be used within the IO Monad (or any other MonadCatch instance) to throw an Exception described by a ReifiedPrism.

Although throwingM has a type that is a specialization of the type of throwing, the two functions are subtly different:

throwing l e `seq` x  ≡ throwing e
throwingM l e `seq` x ≡ x

The first example will cause the Exception e to be raised, whereas the second one won't. In fact, throwingM will only cause an Exception to be raised when it is used within the MonadCatch instance. The throwingM variant should be used in preference to throwing to raise an Exception within the Monad because it guarantees ordering with respect to other monadic operations, whereas throwing does not.

throwingM l ≡ reviews l throw
throwingM :: MonadThrow m => Prism' SomeException t -> t -> m r
throwingM :: MonadThrow m => Iso' SomeException t   -> t -> m r

throwingTo :: MonadIO m => ThreadId -> AReview SomeException b -> b -> m () Source #

throwingTo raises an Exception specified by a ReifiedPrism in the target thread.

throwingTo thread l ≡ reviews l (throwTo thread)
throwingTo :: ThreadId -> Prism' SomeException t -> t -> m a
throwingTo :: ThreadId -> Iso' SomeException t   -> t -> m a

Mapping

mappedException :: (Exception e, Exception e') => Setter s s e e' Source #

This ReifiedSetter can be used to purely map over the Exceptions an arbitrary expression might throw; it is a variant of mapException in the same way that mapped is a variant of fmap.

'mapException' ≡ 'over' 'mappedException'

This view that every Haskell expression can be regarded as carrying a bag of Exceptions is detailed in “A Semantics for Imprecise Exceptions” by Peyton Jones & al. at PLDI ’99.

The following maps failed assertions to arithmetic overflow:

>>> handling _Overflow (\_ -> return "caught") $ assert False (return "uncaught") & mappedException %~ \ (AssertionFailed _) -> Overflow
"caught"

mappedException' :: Exception e' => Setter s s SomeException e' Source #

This is a type restricted version of mappedException, which avoids the type ambiguity in the input Exception when using set.

The following maps any exception to arithmetic overflow:

>>> handling _Overflow (\_ -> return "caught") $ assert False (return "uncaught") & mappedException' .~ Overflow
"caught"

Exceptions

exception :: Exception a => Prism' SomeException a Source #

Traverse the strongly typed Exception contained in SomeException where the type of your function matches the desired Exception.

exception :: (Applicative f, Exception a)
          => (a -> f a) -> SomeException -> f SomeException

pattern Exception :: forall a. Exception a => a -> SomeException Source #

Exception Handlers

class Handleable e (m :: * -> *) (h :: * -> *) | h -> e m where Source #

Both exceptions and Control.Exception provide a Handler type.

This lets us write combinators to build handlers that are agnostic about the choice of which of these they use.

Minimal complete definition

handler

Methods

handler :: Typeable a => Getting (First a) e a -> (a -> m r) -> h r Source #

This builds a Handler for just the targets of a given Prism (or any Getter, really).

catches ... [ handler _AssertionFailed (s -> print $ "Assertion Failed\n" ++ s)
            , handler _ErrorCall (s -> print $ "Error\n" ++ s)
            ]

This works ith both the Handler type provided by Control.Exception:

handler :: Getter     SomeException a -> (a -> IO r) -> Handler r
handler :: Fold       SomeException a -> (a -> IO r) -> Handler r
handler :: Prism'     SomeException a -> (a -> IO r) -> Handler r
handler :: Lens'      SomeException a -> (a -> IO r) -> Handler r
handler :: Traversal' SomeException a -> (a -> IO r) -> Handler r

and with the Handler type provided by Control.Monad.Catch:

handler :: Getter     SomeException a -> (a -> m r) -> Handler m r
handler :: Fold       SomeException a -> (a -> m r) -> Handler m r
handler :: Prism'     SomeException a -> (a -> m r) -> Handler m r
handler :: Lens'      SomeException a -> (a -> m r) -> Handler m r
handler :: Traversal' SomeException a -> (a -> m r) -> Handler m r

and with the Handler type provided by Control.Monad.Error.Lens:

handler :: Getter     e a -> (a -> m r) -> Handler e m r
handler :: Fold       e a -> (a -> m r) -> Handler e m r
handler :: Prism'     e a -> (a -> m r) -> Handler e m r
handler :: Lens'      e a -> (a -> m r) -> Handler e m r
handler :: Traversal' e a -> (a -> m r) -> Handler e m r

handler_ :: Typeable a => Getting (First a) e a -> m r -> h r Source #

This builds a Handler for just the targets of a given Prism (or any Getter, really). that ignores its input and just recovers with the stated monadic action.

catches ... [ handler_ _NonTermination (return "looped")
            , handler_ _StackOverflow (return "overflow")
            ]

This works with the Handler type provided by Control.Exception:

handler_ :: Getter     SomeException a -> IO r -> Handler r
handler_ :: Fold       SomeException a -> IO r -> Handler r
handler_ :: Prism'     SomeException a -> IO r -> Handler r
handler_ :: Lens'      SomeException a -> IO r -> Handler r
handler_ :: Traversal' SomeException a -> IO r -> Handler r

and with the Handler type provided by Control.Monad.Catch:

handler_ :: Getter     SomeException a -> m r -> Handler m r
handler_ :: Fold       SomeException a -> m r -> Handler m r
handler_ :: Prism'     SomeException a -> m r -> Handler m r
handler_ :: Lens'      SomeException a -> m r -> Handler m r
handler_ :: Traversal' SomeException a -> m r -> Handler m r

and with the Handler type provided by Control.Monad.Error.Lens:

handler_ :: Getter     e a -> m r -> Handler e m r
handler_ :: Fold       e a -> m r -> Handler e m r
handler_ :: Prism'     e a -> m r -> Handler e m r
handler_ :: Lens'      e a -> m r -> Handler e m r
handler_ :: Traversal' e a -> m r -> Handler e m r
Instances
Handleable SomeException IO Handler Source # 
Instance details

Defined in Control.Lens.Internal.Exception

Methods

handler :: Typeable a => Getting (First a) SomeException a -> (a -> IO r) -> Handler r Source #

handler_ :: Typeable a => Getting (First a) SomeException a -> IO r -> Handler r Source #

Typeable m => Handleable SomeException m (Handler m) Source # 
Instance details

Defined in Control.Lens.Internal.Exception

Methods

handler :: Typeable a => Getting (First a) SomeException a -> (a -> m r) -> Handler m r Source #

handler_ :: Typeable a => Getting (First a) SomeException a -> m r -> Handler m r Source #

Handleable e m (Handler e m) Source # 
Instance details

Defined in Control.Monad.Error.Lens

Methods

handler :: Typeable a => Getting (First a) e a -> (a -> m r) -> Handler e m r Source #

handler_ :: Typeable a => Getting (First a) e a -> m r -> Handler e m r Source #

IOExceptions

class AsIOException t where Source #

Exceptions that occur in the IO Monad. An IOException records a more specific error type, a descriptive string and maybe the handle that was used when the error was flagged.

Due to their richer structure relative to other exceptions, these have a more carefully overloaded signature.

Methods

_IOException :: Prism' t IOException Source #

Unfortunately the name ioException is taken by base for throwing IOExceptions.

_IOException :: Prism' IOException IOException
_IOException :: Prism' SomeException IOException

Many combinators for working with an IOException are available in System.IO.Error.Lens.

pattern IOException_ :: forall s. AsIOException s => IOException -> s Source #

Arithmetic Exceptions

pattern ArithException_ :: forall s. AsArithException s => ArithException -> s Source #

pattern Overflow_ :: forall s. AsArithException s => s Source #

pattern Underflow_ :: forall s. AsArithException s => s Source #

pattern LossOfPrecision_ :: forall s. AsArithException s => s Source #

pattern DivideByZero_ :: forall s. AsArithException s => s Source #

pattern Denormal_ :: forall s. AsArithException s => s Source #

pattern RatioZeroDenominator_ :: forall s. AsArithException s => s Source #

Array Exceptions

pattern ArrayException_ :: forall s. AsArrayException s => ArrayException -> s Source #

pattern IndexOutOfBounds_ :: forall s. AsArrayException s => String -> s Source #

pattern UndefinedElement_ :: forall s. AsArrayException s => String -> s Source #

Assertion Failed

pattern AssertionFailed_ :: forall s. AsAssertionFailed s => String -> s Source #

Async Exceptions

_StackOverflow :: AsAsyncException t => Prism' t () Source #

The current thread's stack exceeded its limit. Since an Exception has been raised, the thread's stack will certainly be below its limit again, but the programmer should take remedial action immediately.

_StackOverflow :: Prism' AsyncException ()
_StackOverflow :: Prism' SomeException  ()

_HeapOverflow :: AsAsyncException t => Prism' t () Source #

The program's heap is reaching its limit, and the program should take action to reduce the amount of live data it has.

Notes:

  • It is undefined which thread receives this Exception.
  • GHC currently does not throw HeapOverflow exceptions.
_HeapOverflow :: Prism' AsyncException ()
_HeapOverflow :: Prism' SomeException  ()

_ThreadKilled :: AsAsyncException t => Prism' t () Source #

This Exception is raised by another thread calling killThread, or by the system if it needs to terminate the thread for some reason.

_ThreadKilled :: Prism' AsyncException ()
_ThreadKilled :: Prism' SomeException  ()

_UserInterrupt :: AsAsyncException t => Prism' t () Source #

This Exception is raised by default in the main thread of the program when the user requests to terminate the program via the usual mechanism(s) (e.g. Control-C in the console).

_UserInterrupt :: Prism' AsyncException ()
_UserInterrupt :: Prism' SomeException  ()

pattern AsyncException_ :: forall s. AsAsyncException s => AsyncException -> s Source #

pattern StackOverflow_ :: forall s. AsAsyncException s => s Source #

pattern HeapOverflow_ :: forall s. AsAsyncException s => s Source #

pattern ThreadKilled_ :: forall s. AsAsyncException s => s Source #

pattern UserInterrupt_ :: forall s. AsAsyncException s => s Source #

Non-Termination

class AsNonTermination t where Source #

Thrown when the runtime system detects that the computation is guaranteed not to terminate. Note that there is no guarantee that the runtime system will notice whether any given computation is guaranteed to terminate or not.

Minimal complete definition

__NonTermination

pattern NonTermination_ :: forall s. AsNonTermination s => s Source #

Nested Atomically

pattern NestedAtomically_ :: forall s. AsNestedAtomically s => s Source #

Blocked Indefinitely

on MVar

on STM

Deadlock

class AsDeadlock t where Source #

There are no runnable threads, so the program is deadlocked. The Deadlock Exception is raised in the main thread only.

Minimal complete definition

__Deadlock

pattern Deadlock__ :: forall s. AsDeadlock s => Deadlock -> s Source #

pattern Deadlock_ :: forall s. AsDeadlock s => s Source #

No Such Method

pattern NoMethodError__ :: forall s. AsNoMethodError s => NoMethodError -> s Source #

pattern NoMethodError_ :: forall s. AsNoMethodError s => String -> s Source #

Pattern Match Failure

pattern PatternMatchFail_ :: forall s. AsPatternMatchFail s => String -> s Source #

Record

class AsRecSelError t where Source #

A record selector was applied to a constructor without the appropriate field. This can only happen with a datatype with multiple constructors, where some fields are in one constructor but not another.

Minimal complete definition

__RecSelError

class AsRecUpdError t where Source #

A record update was performed on a constructor without the appropriate field. This can only happen with a datatype with multiple constructors, where some fields are in one constructor but not another.

Minimal complete definition

__RecUpdError

pattern RecConError__ :: forall s. AsRecConError s => RecConError -> s Source #

pattern RecConError_ :: forall s. AsRecConError s => String -> s Source #

pattern RecSelError__ :: forall s. AsRecSelError s => RecSelError -> s Source #

pattern RecSelError_ :: forall s. AsRecSelError s => String -> s Source #

pattern RecUpdError__ :: forall s. AsRecUpdError s => RecUpdError -> s Source #

pattern RecUpdError_ :: forall s. AsRecUpdError s => String -> s Source #

Error Call

class AsErrorCall t where Source #

This is thrown when the user calls error.

Minimal complete definition

__ErrorCall

Methods

__ErrorCall :: Prism' t ErrorCall Source #

_ErrorCall :: Prism' t String Source #

Retrieve the argument given to error.

ErrorCall is isomorphic to a String.

>>> catching _ErrorCall (error "touch down!") return
"touch down!"
_ErrorCall :: Prism' ErrorCall     String
_ErrorCall :: Prism' SomeException String

pattern ErrorCall__ :: forall s. AsErrorCall s => ErrorCall -> s Source #

pattern ErrorCall_ :: forall s. AsErrorCall s => String -> s Source #

Allocation Limit Exceeded

Type Error

class AsTypeError t where Source #

An expression that didn't typecheck during compile time was called. This is only possible with -fdefer-type-errors.

Minimal complete definition

__TypeError

pattern TypeError__ :: forall s. AsTypeError s => TypeError -> s Source #

pattern TypeError_ :: forall s. AsTypeError s => String -> s Source #

Compaction Failed

pattern CompactionFailed_ :: forall s. AsCompactionFailed s => String -> s Source #

Handling Exceptions

pattern HandlingException_ :: forall s. AsHandlingException s => s Source #