packages feed

rescue 0.2.1 → 0.3.0

raw patch · 10 files changed

+349/−142 lines, 10 filesdep +transformers-base

Dependencies added: transformers-base

Files

README.md view
@@ -36,6 +36,7 @@   * e.g. "can raise X, Y, and Z", or "raises exactly X and Y but none others" * Extensible * Ability to call code that raises some subset of errors+* Handle (and eliminate) exceptions from the context  # Approach 
library/Control/Monad/Cleanup/Class.hs view
@@ -1,18 +1,17 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies     #-}+{-# LANGUAGE TypeOperators    #-}  module Control.Monad.Cleanup.Class (MonadCleanup (..)) where  import           Control.Exception import           Control.Monad.Rescue -import           Data.WorldPeace- -- | Safely work with resources when an asynchronous exception may be thrown-class (Raises m SomeException, MonadRescue m) => MonadCleanup m where+class (m `Raises` SomeException, MonadRescueFrom m m) => MonadCleanup m where   cleanup-    :: m resource                                   -- ^ Acquire some resource-    -> (resource -> OpenUnion (Errors m) -> m _ig1) -- ^ Cleanup and re-raise-    -> (resource ->                         m _ig2) -- ^ Cleanup normally-    -> (resource ->                         m a)    -- ^ Inner action to perform with the resource+    :: m resource                          -- ^ Acquire some resource+    -> (resource -> ErrorCase m -> m _ig1) -- ^ Cleanup and re-raise+    -> (resource ->                m _ig2) -- ^ Cleanup normally+    -> (resource ->                m a)    -- ^ Inner action to perform with the resource     -> m a
library/Control/Monad/Raise/Class.hs view
@@ -3,12 +3,16 @@ {-# LANGUAGE FlexibleInstances    #-} {-# LANGUAGE MagicHash            #-} {-# LANGUAGE TypeFamilies         #-}+{-# LANGUAGE TypeOperators        #-} {-# LANGUAGE UndecidableInstances #-}  -- | The 'MonadRaise' class, which is an effect for --   early escape / happy path programming with an exception side channel -module Control.Monad.Raise.Class (MonadRaise (..)) where+module Control.Monad.Raise.Class+  ( MonadRaise (..)+  , ErrorCase+  ) where  import           Control.Exception @@ -86,8 +90,11 @@   --   -- >>> maybeBoom 42   -- Nothing-  raise :: Subset err (OpenUnion (Errors m)) => err -> m a+  raise :: Subset err (ErrorCase m) => err -> m a +-- | Type alias representing the concrete union of the monad's errors+type ErrorCase m = OpenUnion (Errors m)+ instance MonadRaise [] where   type Errors [] = '[()]   raise _ = []@@ -121,9 +128,13 @@   type Errors (IdentityT m) = Errors m   raise = lift . raise -instance MonadRaise m => MonadRaise (MaybeT m) where-  type Errors (MaybeT m) = Errors m-  raise = lift . raise+instance+  ( () `IsMember` Errors m+  , MonadRaise m+  )+  => MonadRaise (MaybeT m) where+    type Errors (MaybeT m) = Errors m+    raise err = MaybeT $ raise err  instance MonadRaise m => MonadRaise (ReaderT cfg m) where   type Errors (ReaderT cfg m) = Errors m
library/Control/Monad/Raise/Constraint.hs view
@@ -4,9 +4,15 @@  -- | Declare which exceptions may be raised/rescued in a given context module Control.Monad.Raise.Constraint-  ( Raises+  ( -- * Permissive++    Raises   , RaisesAtLeast++    -- * Precise+   , RaisesOnly+  , RaisesOne   ) where  import           Control.Monad.Raise.Class@@ -15,10 +21,14 @@ import           Data.WorldPeace.Subset.Class  -- | Raises this exception, but potentially others-type Raises m err = Subset err (OpenUnion (Errors m))+type Raises m err = Subset err (ErrorCase m)  -- | May raise errors, including the provided list-type RaisesAtLeast m errs = Subset (OpenUnion errs) (OpenUnion (Errors m))+type RaisesAtLeast m errs = Subset (OpenUnion errs) (ErrorCase m)  -- | Restrict exceptions to exactly this list type RaisesOnly m errs = errs ~ Errors m++-- | Raises an exception, guaranteed to NOT be the outer union+type RaisesOne m err = IsMember err (Errors m)+
library/Control/Monad/Rescue.hs view
@@ -1,5 +1,7 @@-{-# LANGUAGE LambdaCase   #-}-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE LambdaCase       #-}+{-# LANGUAGE TypeFamilies     #-}+{-# LANGUAGE TypeOperators    #-}  -- | Rescue semantics & helpers --@@ -11,6 +13,10 @@  module Control.Monad.Rescue   ( rescue+  , handle++  -- * Guaranteed runs+   , reattempt   , onRaise   , lastly@@ -18,14 +24,18 @@   -- * Reexports    , module Control.Monad.Raise+   , module Control.Monad.Rescue.Class+  , module Control.Monad.Rescue.Constraint   ) where  import           Data.Result.Types import           Data.WorldPeace  import           Control.Monad.Raise+ import           Control.Monad.Rescue.Class+import           Control.Monad.Rescue.Constraint  import           Numeric.Natural @@ -57,17 +67,28 @@ -- :} -- -- >>> handler = catchesOpenUnion (\foo -> "Foo: " <> show foo, \bar -> "Bar:" <> show bar)--- >>> rescue (goesBoom 42) (pure . handler)+-- >>> rescue (goesBoom 42) (pure . handler) :: Rescue MyErrs String -- RescueT (Identity (Right "Foo: FooErr")) rescue-  :: ( MonadRescue m-     , RaisesOnly  m errs-     )-  => m a-  -> (OpenUnion errs -> m a)+  :: MonadRescueFrom n m+  => n a+  -> (ErrorCase n -> m a)   -> m a rescue action handler = either handler pure =<< attempt action +handle+  :: ( MonadRaise        m+     , MonadRescueFrom n m+     , Handles     err n m+     )+  => n a+  -> (err -> m a)+  -> m a+handle action handler =+  either runHandler pure =<< attempt action+  where+    runHandler = openUnionHandle raise handler+ onRaise   :: ( MonadRescue m      , RaisesOnly  m errs@@ -96,7 +117,14 @@  -- | Run an additional step, and throw away the result. --   Return the result of the action passed.-lastly :: (Contains (Errors m) (Errors m), MonadRescue m) => m a -> m b -> m a+lastly+  :: ( Errors m `Contains` Errors m+     , MonadRaise m+     , MonadRescueFrom m m+     )+  => m a+  -> m b+  -> m a lastly action finalizer = do   errOrOk <- attempt action   _       <- finalizer
library/Control/Monad/Rescue/Class.hs view
@@ -1,39 +1,39 @@-{-# LANGUAGE FlexibleContexts     #-}-{-# LANGUAGE FlexibleInstances    #-}-{-# LANGUAGE LambdaCase           #-}-{-# LANGUAGE TypeFamilies         #-}-{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE LambdaCase            #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UndecidableInstances  #-}  -- | The 'MonadRescue' class, meant for retrieving the success/failure branches -module Control.Monad.Rescue.Class (MonadRescue (..)) where+module Control.Monad.Rescue.Class (MonadRescueFrom (..)) where  import           Data.Functor- import           Data.WorldPeace  import           Exception -import           Control.Monad.Raise.Class-import           Control.Monad.Raise.Constraint-+import           Control.Monad.Base import           Control.Monad.Cont +import           Control.Monad.Raise+ import           Control.Monad.Trans.Except import           Control.Monad.Trans.Identity import           Control.Monad.Trans.Maybe import           Control.Monad.Trans.Reader -import qualified Control.Monad.RWS.Lazy         as Lazy-import qualified Control.Monad.RWS.Strict       as Strict--import qualified Control.Monad.State.Lazy       as Lazy-import qualified Control.Monad.State.Strict     as Strict+import qualified Control.Monad.RWS.Lazy       as Lazy+import qualified Control.Monad.RWS.Strict     as Strict -import qualified Control.Monad.Writer.Lazy      as Lazy-import qualified Control.Monad.Writer.Strict    as Strict+import qualified Control.Monad.State.Lazy     as Lazy+import qualified Control.Monad.State.Strict   as Strict -import           Data.WorldPeace.Subset.Class+import qualified Control.Monad.Writer.Lazy    as Lazy+import qualified Control.Monad.Writer.Strict  as Strict  -- $setup --@@ -42,6 +42,7 @@ -- >>> :set -XTypeApplications -- -- >>> import Control.Monad.Trans.Rescue+-- >>> import Data.Functor.Identity -- >>> import Data.Proxy -- >>> import Data.WorldPeace as OpenUnion --@@ -50,7 +51,8 @@ -- >>> data QuuxErr = QuuxErr deriving Show  -- | Pull a potential error out of the surrounding context-class MonadRaise m => MonadRescue m where+-- NOTE that the target `m` may not even be aware of Raise/Rescue. It's an escape to the "normal" world+class (Monad m, MonadRaise n) => MonadRescueFrom n m where   -- | Attempt some action, exposing the success and error branches   --   --  ==== __Examples__@@ -63,96 +65,187 @@   --        else raise FooErr   -- :}   ---  -- >>> runRescue . attempt $ goesBoom 42-  -- Right (Left (Identity FooErr))+  -- >>> :{+  --   result :: Identity (Either (OpenUnion '[FooErr, BarErr]) Int)+  --   result = attempt $ goesBoom 42+  -- :}   ---  -- Where @Identity fooErr@ is the selection of the 'OpenUnion'.-  -- In practice you would handle the 'OpenUnion' like so:+  -- >>> result+  -- Identity (Left (Identity FooErr))   ---  -- >>> let handleErr = catchesOpenUnion (show, show)-  -- >>> let x = attempt (goesBoom 42) >>= pure . either handleErr show-  -- >>> runRescue x-  -- Right "FooErr"-  attempt :: m a -> m (Either (OpenUnion (Errors m)) a)+  -- Where @Identity FooErr@ is the selection of the 'OpenUnion'.+  attempt :: n a -> m (Either (ErrorCase n) a) -instance MonadRescue Maybe where-  attempt = return . \case+instance Monad n => MonadRescueFrom Maybe n where+  attempt = pure . \case     Nothing -> Left $ openUnionLift ()     Just x  -> Right x -instance MonadRescue [] where+instance Monad m => MonadRescueFrom [] m where   attempt = return . \case     []      -> Left $ include ()     (a : _) -> Right a -instance MonadRescue (Either (OpenUnion errs)) where-  attempt action = Right action+instance Monad m => MonadRescueFrom (Either (OpenUnion errs)) m where+  attempt action = pure action -instance MonadRescue IO where+instance MonadIO m => MonadRescueFrom IO m where   attempt action =-    tryIO action <&> \case+    liftIO (tryIO action) <&> \case       Right val  -> Right val       Left ioExc -> Left $ include ioExc -instance MonadRescue m => MonadRescue (MaybeT m) where-  attempt (MaybeT action) = MaybeT . fmap sequence $ attempt action+instance+  ( Monad m+  , MonadRescueFrom n m+  , n `RaisesOne` ()+  )+  => MonadRescueFrom (MaybeT n) m where+    attempt (MaybeT action) =+      attempt action <&> \case+        Right (Just val) -> Right val+        Right Nothing    -> Left $ include ()+        Left errs        -> Left errs -instance MonadRescue m => MonadRescue (IdentityT m) where-  attempt (IdentityT action) = lift (attempt action)+instance MonadRescueFrom n m => MonadRescueFrom (IdentityT n) m where+  attempt (IdentityT action) = attempt action  instance-  ( MonadRescue m-  , Contains (Errors m) errs+  ( MonadBase       n m+  , MonadRescueFrom n n+  , Contains (Errors n) errs   )-  => MonadRescue (ExceptT (OpenUnion errs) m) where-  attempt (ExceptT action) =-    lift $-      attempt action <&> \case-        Left err       -> Left $ include err-        Right errOrVal -> errOrVal+  => MonadRescueFrom n (ExceptT (OpenUnion errs) m) where+    attempt = liftBase . attempt -instance MonadRescue m => MonadRescue (ReaderT cfg m) where-  attempt = mapReaderT attempt+instance+  ( Monad             m+  , MonadBase       n m+  , MonadRaise      n+  , MonadRescueFrom n m+  )+  => MonadRescueFrom (ReaderT cfg n) (ReaderT cfg m) where+    attempt = mapReaderT attempt -instance (Monoid w, MonadRescue m) => MonadRescue (Lazy.WriterT w m) where-  attempt = Lazy.mapWriterT runner2+instance+  ( Monad               m+  , MonadBase       n   m+  , MonadRaise      n+  , MonadRescueFrom n n+  )+  => MonadRescueFrom n (ReaderT cfg m) where+    attempt = liftBase . attempt -instance (Monoid w, MonadRescue m) => MonadRescue (Strict.WriterT w m) where-  attempt = Strict.mapWriterT runner2+instance+  ( Monoid w+  , MonadBase       n m+  , MonadRescueFrom n m+  )+  => MonadRescueFrom (Lazy.WriterT w n) (Lazy.WriterT w m) where+    attempt = Lazy.mapWriterT runner2 -instance MonadRescue m => MonadRescue (Lazy.StateT s m) where-  attempt = Lazy.mapStateT runner2+instance+  ( Monoid w+  , MonadBase       n m+  , MonadRescueFrom n n+  )+  => MonadRescueFrom n (Lazy.WriterT w m) where+    attempt = liftBase . attempt -instance MonadRescue m => MonadRescue (Strict.StateT s m) where-  attempt = Strict.mapStateT runner2+instance+  ( Monoid w+  , MonadBase       n m+  , MonadRescueFrom n m+  )+  => MonadRescueFrom (Strict.WriterT w n) (Strict.WriterT w m) where+    attempt = Strict.mapWriterT runner2 -instance (Monoid w, MonadRescue m) => MonadRescue (Lazy.RWST r w s m) where-  attempt = Lazy.mapRWST runner3+instance+  ( Monoid w+  , MonadBase       n m+  , MonadRescueFrom n n+  )+  => MonadRescueFrom n (Strict.WriterT w m) where+    attempt = liftBase . attempt -instance (Monoid w, MonadRescue m) => MonadRescue (Strict.RWST r w s m) where-  attempt = Strict.mapRWST runner3+instance+  ( MonadBase       n m+  , MonadRescueFrom n m+  )+  => MonadRescueFrom (Lazy.StateT s n) (Lazy.StateT s m) where+    attempt = Lazy.mapStateT runner2 -instance MonadRescue m => MonadRescue (ContT r m) where-  attempt = withContT $ \b_mr current -> b_mr =<< attempt (pure current)+instance+  ( MonadBase       n m+  , MonadRescueFrom n n+  )+  => MonadRescueFrom n (Lazy.StateT s m) where+    attempt = liftBase . attempt +instance+  ( MonadBase       n m+  , MonadRescueFrom n m+  )+  => MonadRescueFrom (Strict.StateT s n) (Strict.StateT s m) where+    attempt = Strict.mapStateT runner2++instance+  ( Monoid w+  , MonadBase n m+  , MonadRescueFrom n m+  )+  => MonadRescueFrom (Lazy.RWST r w s n) (Lazy.RWST r w s m) where+    attempt = Lazy.mapRWST runner3++instance+  ( MonadBase       n m+  , MonadRescueFrom n n+  )+  => MonadRescueFrom n (Strict.StateT s m) where+    attempt = liftBase . attempt++instance+  ( Monoid w+  , MonadBase       n m+  , MonadRescueFrom n n+  )+  => MonadRescueFrom n (Strict.RWST r w s m) where+    attempt = liftBase . attempt++instance+  ( MonadBase       n m+  , MonadRescueFrom n n+  )+  => MonadRescueFrom n (ContT r m) where+    attempt = liftBase . attempt++instance forall m r . (MonadRescueFrom (ContT r m) m) => MonadRescueFrom (ContT r m) (ContT r m) where+  attempt =+    withContT $ \b_mr (current :: a) ->+      b_mr =<< attempt (pure current :: ContT r m a)+ runner2-  :: ( MonadRescue m-     , RaisesOnly  m errs+  :: forall m n errs a w .+     ( MonadBase n m+     , MonadRescueFrom n m+     , n `RaisesOnly` errs      )-  => m (a, w)-  -> m (Either (OpenUnion errs) a, w)+  => n (a, w)+  -> m (Either (ErrorCase n) a, w) runner2 inner = do-  (a, w)   <- inner-  errOrVal <- attempt (pure a)-  return (errOrVal, w)+  (val, log')  <- liftBase inner+  result <- attempt (pure val :: n a)+  return (result, log')  runner3-  :: ( MonadRescue m-     , RaisesOnly  m errs+  :: forall m n errs a s w .+     ( MonadBase       n m+     , MonadRescueFrom n m+     , n `RaisesOnly` errs      )-  => m (a, b, c)-  -> m (Either (OpenUnion errs) a, b, c)+  => n (a, s, w)+  -> m (Either (OpenUnion errs) a, s, w) runner3 inner = do-  (a, s, w) <- inner-  errOrVal  <- attempt (pure a)-  return (errOrVal, s, w)+  (val, state, log') <- liftBase inner+  result             <- attempt (pure val :: n a)+  return (result, state, log')
+ library/Control/Monad/Rescue/Constraint.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE ConstraintKinds  #-}+{-# LANGUAGE FlexibleContexts #-}++module Control.Monad.Rescue.Constraint+  ( Handles+  , MonadRescue+  ) where++import           Control.Monad.Raise.Class+import           Control.Monad.Rescue.Class++import           Data.WorldPeace++-- | Express the ability to 'handle' / eliminate an exception case+type Handles err n m+  =  ( ElemRemove       err (Errors n)+     , Contains (Remove err (Errors n)) (Errors m)+     )++-- | Rescue from the existing context only+--+-- Note: cannot 'handle' (elimininate) exceptions+type MonadRescue m = MonadRescueFrom m m
library/Control/Monad/Trans/Cleanup/Types.hs view
@@ -1,9 +1,11 @@-{-# LANGUAGE DataKinds            #-}-{-# LANGUAGE LambdaCase           #-}-{-# LANGUAGE ScopedTypeVariables  #-}-{-# LANGUAGE TypeFamilies         #-}-{-# LANGUAGE TypeOperators        #-}-{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE LambdaCase            #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UndecidableInstances  #-}  -- | The 'CleanupT' transformer for adding async exceptions to a stack @@ -15,13 +17,16 @@ import           Control.Applicative import           Control.Monad +import           Control.Monad.Base import           Control.Monad.Catch        as Catch import           Control.Monad.Cleanup import           Control.Monad.Fix import           Control.Monad.IO.Class import           Control.Monad.Trans.Class +import           Data.Functor import           Data.Functor.Contravariant+ import           Data.WorldPeace  -- | Adds 'SomeException' to an exception stack,@@ -76,33 +81,6 @@ instance MonadThrow m => MonadThrow (CleanupT m) where   throwM = CleanupT . throwM -instance-  ( Contains (Errors m) (Errors m)-  , MonadRaise m-  , MonadThrow m-  )-  => MonadRaise (CleanupT m) where-  type Errors (CleanupT m) = SomeException ': Errors m--  raise err = openUnion raiser throwM errsUnion-    where-      errsUnion :: OpenUnion (SomeException ': Errors m)-      errsUnion = include err--      raiser :: Contains err (Errors m) => OpenUnion err -> CleanupT m a-      raiser = CleanupT . raise--instance-  ( Contains (Errors m) (Errors m)-  , MonadCatch  m-  , MonadRescue m-  )-  => MonadRescue (CleanupT m) where-  attempt action =-    Catch.try action >>= \case-      Left  e@(SomeException _) -> return . Left $ include e-      Right result              -> attempt $ pure result- instance MonadCatch m => MonadCatch (CleanupT m) where   catch (CleanupT action) handler =     CleanupT $ catch action (runCleanupT . handler)@@ -127,7 +105,51 @@  instance   ( Contains (Errors m) (Errors m)+  , MonadRaise m+  , MonadThrow m+  )+  => MonadRaise (CleanupT m) where+  type Errors (CleanupT m) = SomeException ': Errors m++  raise err = openUnion raiser throwM errsUnion+    where+      errsUnion :: OpenUnion (SomeException ': Errors m)+      errsUnion = include err++      raiser :: Contains err (Errors m) => OpenUnion err -> CleanupT m a+      raiser = CleanupT . raise++instance MonadBase m m => MonadBase m (CleanupT m) where+  liftBase = liftBaseDefault++instance (Monad m, MonadRescue m) => MonadRescueFrom m (CleanupT m) where+  attempt = CleanupT . attempt++instance forall n m .+  ( MonadRescueFrom n m+  , MonadBase       n m+  , MonadRescue     n+  , MonadCatch      n+  , Contains (Errors n) (Errors n)+  , Contains (Errors n) (SomeException ': Errors n)+  )+  => MonadRescueFrom (CleanupT n) m where+    attempt (CleanupT action) =+      liftBase $+        inner <&> \case+          Left err          -> Left $ include err+          Right (Left  err) -> Left $ include err+          Right (Right val) -> Right val+      where+        inner =+          Catch.try action >>= \case+            Left  e@(SomeException _) -> return $ Left e+            Right (val :: a)          -> Right <$> attempt (pure val :: n a)++instance+  ( Contains (Errors m) (Errors m)   , Contains (Errors m) (SomeException ': Errors m)+  , MonadBase m m   , MonadRescue m   , MonadMask   m   )
library/Control/Monad/Trans/Rescue/Types.hs view
@@ -12,11 +12,14 @@   , runRescue   ) where +import Prelude+ import           Control.Monad.Catch import           Control.Monad.Cont import           Control.Monad.Fix import           Control.Monad.Reader import           Control.Monad.Rescue+import           Control.Monad.Base  import           Data.Functor.Identity import           Data.WorldPeace@@ -32,9 +35,12 @@ runRescue = runIdentity . runRescueT  mapRescueT-  :: (m (Either (OpenUnion errs)  a) -> n (Either (OpenUnion errs') b))-  -> RescueT errs m a -> RescueT errs' n b-mapRescueT f (RescueT m) = RescueT $ f m+  :: (  n (Either (OpenUnion errs)  a)+     -> m (Either (OpenUnion errs') b)+     )+  -> RescueT errs  n a+  -> RescueT errs' m b+mapRescueT f (RescueT n) = RescueT $ f n  instance Eq (m (Either (OpenUnion errs) a)) => Eq (RescueT errs m a) where   RescueT a == RescueT b = a == b@@ -60,6 +66,9 @@ instance MonadTrans (RescueT errs) where   lift action = RescueT (Right <$> action) +instance MonadBase b m => MonadBase b (RescueT errs m) where+  liftBase = liftBaseDefault+ instance MonadIO m => MonadIO (RescueT errs m) where   liftIO io = RescueT $ do     action <- liftIO io@@ -86,8 +95,12 @@   type Errors (RescueT errs m) = errs   raise err = RescueT . pure $ raise err -instance Monad m => MonadRescue (RescueT errs m) where-  attempt (RescueT action) = RescueT (Right <$> action)+instance+  ( Monad       m+  , MonadBase n m+  )+  => MonadRescueFrom (RescueT errs n) m where+    attempt (RescueT action) = liftBase action  instance MonadThrow m => MonadThrow (RescueT errs m) where   throwM = lift . throwM
rescue.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.33.0.+-- This file has been generated from package.yaml by hpack version 0.34.2. -- -- see: https://github.com/sol/hpack ----- hash: 3e4995b89bcb6d9791c2c448d52d59c9ca79e160013ba0d3fbad54936b417fe3+-- hash: 6fb768a7355701f4063e91ba078ad7698c52571f65d298ebcf667cacd6a8b1a8  name:           rescue-version:        0.2.1+version:        0.3.0 synopsis:       More understandable exceptions description:    An error handling library focused on clarity and control category:       Error Handling@@ -36,6 +36,7 @@       Control.Monad.Raise.Constraint       Control.Monad.Rescue       Control.Monad.Rescue.Class+      Control.Monad.Rescue.Constraint       Control.Monad.Trans.Cleanup       Control.Monad.Trans.Cleanup.Types       Control.Monad.Trans.Rescue@@ -58,6 +59,7 @@     , mtl     , text     , transformers+    , transformers-base     , world-peace   default-language: Haskell2010 @@ -83,6 +85,7 @@     , quickcheck-instances     , text     , transformers+    , transformers-base     , world-peace     , yaml   default-language: Haskell2010@@ -104,6 +107,7 @@     , rio     , text     , transformers+    , transformers-base     , world-peace   default-language: Haskell2010 @@ -118,6 +122,7 @@       Control.Monad.Raise.Constraint       Control.Monad.Rescue       Control.Monad.Rescue.Class+      Control.Monad.Rescue.Constraint       Control.Monad.Trans.Cleanup       Control.Monad.Trans.Cleanup.Types       Control.Monad.Trans.Rescue@@ -151,6 +156,7 @@     , tasty-smallcheck     , text     , transformers+    , transformers-base     , world-peace   default-language: Haskell2010 @@ -171,5 +177,6 @@     , rescue     , text     , transformers+    , transformers-base     , world-peace   default-language: Haskell2010