asynchronous-exceptions (empty) → 1.0
raw patch · 4 files changed
+132/−0 lines, 4 filesdep +basesetup-changed
Dependencies added: base
Files
- Control/Exception/Async.hs +86/−0
- LICENSE +19/−0
- Setup.hs +2/−0
- asynchronous-exceptions.cabal +25/−0
+ Control/Exception/Async.hs view
@@ -0,0 +1,86 @@+{-# LANGUAGE DeriveDataTypeable, ExistentialQuantification #-}+-- |+-- It is often useful to distinguish between synchronous and asynchronous+-- exceptions. The common idiom is to run a user-supplied computation+-- catching any synchronous exceptions but allowing asynchronous exceptions+-- (such as user interrupt) pass through.+--+-- There's no way to know how — synchronously or asynchronously — an+-- exception was thrown, so we have to work around it by relying on the+-- exception type itself.+--+-- This module provides an extensible type for asynchronous exceptions+-- — 'SomeAsyncException' — as well as functions for catching synchronous+-- exceptions.++module Control.Exception.Async+ ( SomeAsyncException+ , asyncToException+ , asyncFromException+ , isAsynchronous+ , catchSync+ , handleSync+ , trySync+ )+ where++import Control.Exception as E+import Control.Monad+import Data.Typeable+import Data.Maybe++-- | Exception class for asynchronous exceptions.+--+-- To mark an exception as asynchronous:+--+-- >instance Exception MyException where+-- > fromException = asyncFromException+-- > toException = asyncToException+--+-- Note that as of base 4.6, 'AsyncException' is not yet a subclass of+-- 'SomeAsyncException'. Use 'isAsynchronous' to recognize both+-- 'AsyncException' and 'SomeAsyncException'.+data SomeAsyncException+ = forall e . Exception e => SomeAsyncException e+ deriving Typeable++instance Exception SomeAsyncException++instance Show SomeAsyncException where+ showsPrec p (SomeAsyncException e) = showsPrec p e++-- | 'toException' implementation for asynchronous exceptions+asyncToException :: Exception e => e -> SomeException+asyncToException = toException . SomeAsyncException++-- | 'fromException' implementation for asynchronous exceptions+asyncFromException :: Exception e => SomeException -> Maybe e+asyncFromException x = do+ SomeException e <- fromException x+ cast e++-- | Check whether an exception is asynchronous+isAsynchronous :: SomeException -> Bool+isAsynchronous e =+ isJust (fromException e :: Maybe AsyncException) ||+ isJust (fromException e :: Maybe SomeAsyncException)+++-- | Like 'catch', but catch any synchronous exceptions; let asynchronous ones pass through+catchSync :: IO a -> (SomeException -> IO a) -> IO a+catchSync a h =+ E.catch a $ \e ->+ if isAsynchronous e+ then throwIO e+ else h e++-- | Like 'handle', but catch any synchronous exceptions; let asynchronous ones pass through+handleSync :: (SomeException -> IO a) -> IO a -> IO a+handleSync = flip catchSync++-- | Like 'try', but catch any synchronous exceptions; let asynchronous ones pass through+trySync :: IO b -> IO (Either SomeException b)+trySync a =+ catchSync+ (liftM Right a)+ (return . Left)
+ LICENSE view
@@ -0,0 +1,19 @@+Copyright (c) 2014 Roman Cheplyaka++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ asynchronous-exceptions.cabal view
@@ -0,0 +1,25 @@+-- Initial asynchronous-exceptions.cabal generated by cabal init. For+-- further documentation, see http://haskell.org/cabal/users-guide/++name: asynchronous-exceptions+version: 1.0+synopsis: Distinguish between synchronous and asynchronous exceptions+description: Distinguish between synchronous and asynchronous exceptions+homepage: https://github.com/feuerbach/asynchronous-exceptions+license: MIT+license-file: LICENSE+author: Roman Cheplyaka+maintainer: roma@ro-che.info+-- copyright:+category: Control+build-type: Simple+-- extra-source-files:+cabal-version: >=1.10++library+ exposed-modules: Control.Exception.Async+ -- other-modules:+ other-extensions: DeriveDataTypeable, ExistentialQuantification+ build-depends: base >=4.6 && <4.7+ -- hs-source-dirs:+ default-language: Haskell2010