packages feed

errors 2.0.1 → 2.3.0

raw patch · 6 files changed

Files

+ CHANGELOG.md view
@@ -0,0 +1,149 @@+# 2.3.0++* BREAKING CHANGE: `syncIO` now expects a `MonadIO` constraint instead of+  `UnexceptionalIO`+    * `syncIO` also changes how it detects asynchronous exceptions.  It now+      decides based on whether or not an exception inherits from+      `SomeAsyncException`+    * See: https://github.com/Gabriel439/Haskell-Errors-Library/pull/53++# 2.2.5++* Increase upper bound on `exceptions`++# 2.2.4++* Increase upper bound on `exceptions`++# 2.2.3++* Increase upper bound on `transformers-compat`++# 2.2.2++* Support GHC 8.4 through compatibility with Semigroup/Monoid proposal++# 2.2.1++* Add precedence and fixity for `(?:)`++# 2.2.0++* BREAKING CHANGE: Use `Text` instead of `String`+* Add `handleExceptT`++# 2.1.3++* Support older versions of `ghc`++# 2.1.2++* Increase upper bound on `transformers` dependency++# 2.1.1++* Increase upper bound on `transformers-compat`++# 2.1.0++* Change `syncio` to use `unexceptionalio` to prove that all synchronous+  exceptions were caught and handled++# 2.0.0++* Switch from `EitherT` to `ExceptT`++# 1.4.7++* Increase upper bound on `transformers` from `0.4` to `0.5`++# 1.4.6++* Add `bool`+* Add `(?:)`+* Add `isJustT`+* Add `isNothingT`+* Add `isLeftT`+* Add `isRightT`++# 1.4.5++* Increase upper bound on `either` from `4.1` to `5`++# 1.4.4++* Add `failWith`+* Add `failWithM`++# 1.4.3++* Add `AllE`+* Add `AnyE`+* Increase upper bound on `either` from `3.5` to `4.1`++# 1.4.2++* Add `(??)`+* Add `(!?)`+* Add `syncIO`++# 1.4.1++* Re-export `EitherT`+* Re-export `MaybeT`++# 1.4.0++* Add `maybeT`+* Add `just`+* Add `nothing`+* Add upper bound to `either`+* Add upper bound to `safe`+* Add upper bound to `transformers`++# 1.3.1++* Increase lower bound on `transformers` from `0.2` to `0.3.0.0`++# 1.3.0++* Add `assertMay`+* Add `rightMay`+* Add `justErr`+* Add `tryJust`+* Add `tryRight`+* Add `MonadPlus` functions to `Control.Error.Safe`+* Add `isLeft`+* Add `isRight`+* Add `fmapR`+* Add `fmapRT`+* Add `err`+* Add `errLn`+* Add `flipE`+* Add `flipET`+* Rename `tryIO` to `scriptIO`+* Remove `tryMaybe`+* Remove `tryEither`+* Rename `liftMaybe` to `hoistMaybe`+* Rename `liftEither` to `hoistEither`++# 1.2.1++* Add lower bound to `either`++# 1.2.0++* Remove `right`+* Remove `left`++# 1.1.1++* Cosmetic changes++# 1.1.0++* Add `left`++# 1.0.0++* Initial release
Control/Error.hs view
@@ -10,7 +10,7 @@       'EitherT', and 'MonadPlus' variations on total functions      * "Control.Error.Script": Support for simple scripts that catch all errors-      and transform them to 'String's+      and transform them to 'Text'      * "Control.Error.Util": Utility functions and conversions between common       error-handling types
Control/Error/Script.hs view
@@ -1,5 +1,7 @@+{-# LANGUAGE OverloadedStrings #-}+ {-|-    Use this module if you like to write simple scripts with 'String'-based+    Use this module if you like to write simple scripts with 'Text'-based     errors, but you prefer to use 'ExceptT' to handle errors rather than     @Control.Exception@. @@ -24,6 +26,8 @@ import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT) import Control.Error.Util (errLn) import Data.EitherR (fmapL)+import Data.Monoid ((<>))+import Data.Text (Text) import System.Environment (getProgName) import System.Exit (exitFailure) @@ -31,9 +35,11 @@ import Control.Monad.Trans.Class (lift) import System.IO (stderr) --- | An 'IO' action that can fail with a 'String' error message-type Script = ExceptT String IO+import qualified Data.Text +-- | An 'IO' action that can fail with a 'Text' error message+type Script = ExceptT Text IO+ {-| Runs the 'Script' monad      Prints the first error to 'stderr' and exits with 'exitFailure'@@ -43,17 +49,18 @@     e <- runExceptT s     case e of         Left  e -> do-            errLn =<< liftM (++ ": " ++ e) getProgName+            let adapt str = Data.Text.pack str <> ": " <> e+            errLn =<< liftM adapt getProgName             exitFailure         Right a -> return a  {-| 'scriptIO' resembles 'lift', except it catches all exceptions and converts-    them to 'String's.+    them to 'Text'      Note that 'scriptIO' is compatible with the 'Script' monad. -}-scriptIO :: (MonadIO m) => IO a -> ExceptT String m a+scriptIO :: (MonadIO m) => IO a -> ExceptT Text m a scriptIO = ExceptT          . liftIO-         . liftM (fmapL show)+         . liftM (fmapL (Data.Text.pack . show))          . (try :: IO a -> IO (Either SomeException a))
Control/Error/Util.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ -- | This module exports miscellaneous error-handling functions.  module Control.Error.Util (@@ -47,21 +49,28 @@      -- * Exceptions     tryIO,+    handleExceptT,     syncIO     ) where  import Control.Applicative (Applicative, pure, (<$>))-import qualified Control.Exception as Ex+import Control.Exception (IOException, SomeException, Exception) import Control.Monad (liftM)+import Control.Monad.Catch (MonadCatch, try) import Control.Monad.IO.Class (MonadIO(liftIO)) import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT) import Control.Monad.Trans.Maybe (MaybeT(MaybeT), runMaybeT)-import Data.Dynamic (Dynamic) import Data.Monoid (Monoid(mempty, mappend))+#if MIN_VERSION_base(4,9,0)+import Data.Semigroup+#endif import Data.Maybe (fromMaybe)-import System.Exit (ExitCode)-import System.IO (hPutStr, hPutStrLn, stderr)+import Data.Text (Text)+import System.IO (stderr) +import qualified Control.Exception as Exception+import qualified Data.Text.IO+ -- | Fold an 'ExceptT' by providing one continuation for each constructor exceptT :: Monad m => (a -> m c) -> (b -> m c) -> ExceptT a m b -> m c exceptT f g (ExceptT m) = m >>= \z -> case z of@@ -119,6 +128,8 @@ maybeA ?: b = fromMaybe b maybeA {-# INLINABLE (?:) #-} +infixr 0 ?:+ {-| Convert a 'Maybe' value into the 'ExceptT' monad      Named version of ('??') with arguments flipped@@ -187,12 +198,22 @@ -} newtype AllE e r = AllE { runAllE :: Either e r } +#if MIN_VERSION_base(4,9,0)+instance (Semigroup e, Semigroup r) => Semigroup (AllE e r) where+    AllE (Right x) <> AllE (Right y) = AllE (Right (x <> y))+    AllE (Right _) <> AllE (Left  y) = AllE (Left y)+    AllE (Left  x) <> AllE (Right _) = AllE (Left x)+    AllE (Left  x) <> AllE (Left  y) = AllE (Left  (x <> y))+#endif+ instance (Monoid e, Monoid r) => Monoid (AllE e r) where     mempty = AllE (Right mempty)+#if !(MIN_VERSION_base(4,11,0))     mappend (AllE (Right x)) (AllE (Right y)) = AllE (Right (mappend x y))     mappend (AllE (Right _)) (AllE (Left  y)) = AllE (Left y)     mappend (AllE (Left  x)) (AllE (Right _)) = AllE (Left x)     mappend (AllE (Left  x)) (AllE (Left  y)) = AllE (Left  (mappend x y))+#endif  {-| Run multiple 'Either' computations and succeed if any of them succeed @@ -200,12 +221,22 @@ -} newtype AnyE e r = AnyE { runAnyE :: Either e r } +#if MIN_VERSION_base(4,9,0)+instance (Semigroup e, Semigroup r) => Semigroup (AnyE e r) where+    AnyE (Right x) <> AnyE (Right y) = AnyE (Right (x <> y))+    AnyE (Right x) <> AnyE (Left  _) = AnyE (Right x)+    AnyE (Left  _) <> AnyE (Right y) = AnyE (Right y)+    AnyE (Left  x) <> AnyE (Left  y) = AnyE (Left  (x <> y))+#endif+ instance (Monoid e, Monoid r) => Monoid (AnyE e r) where     mempty = AnyE (Right mempty)+#if !(MIN_VERSION_base(4,11,0))     mappend (AnyE (Right x)) (AnyE (Right y)) = AnyE (Right (mappend x y))     mappend (AnyE (Right x)) (AnyE (Left  _)) = AnyE (Right x)     mappend (AnyE (Left  _)) (AnyE (Right y)) = AnyE (Right y)     mappend (AnyE (Left  x)) (AnyE (Left  y)) = AnyE (Left  (mappend x y))+#endif  -- | Analogous to 'isLeft', but for 'ExceptT' isLeftT :: (Monad m) => ExceptT a m b -> m Bool@@ -224,38 +255,30 @@ fmapRT = liftM  -- | Write a string to standard error-err :: String -> IO ()-err = hPutStr stderr+err :: Text -> IO ()+err = Data.Text.IO.hPutStr stderr  -- | Write a string with a newline to standard error-errLn :: String -> IO ()-errLn = hPutStrLn stderr+errLn :: Text -> IO ()+errLn = Data.Text.IO.hPutStrLn stderr --- | Catch 'Ex.IOException's and convert them to the 'ExceptT' monad-tryIO :: (MonadIO m) => IO a -> ExceptT Ex.IOException m a-tryIO = ExceptT . liftIO . Ex.try+-- | Catch 'IOException's and convert them to the 'ExceptT' monad+tryIO :: MonadIO m => IO a -> ExceptT IOException m a+tryIO = ExceptT . liftIO . Exception.try +-- | Run a monad action which may throw an exception in the `ExceptT` monad+handleExceptT :: (Exception e, Functor m, MonadCatch m) => (e -> x) -> m a -> ExceptT x m a+handleExceptT handler = bimapExceptT handler id . ExceptT . try++ {-| Catch all exceptions, except for asynchronous exceptions found in @base@     and convert them to the 'ExceptT' monad -}-syncIO :: MonadIO m => IO a -> ExceptT Ex.SomeException m a-syncIO a = ExceptT . liftIO $ Ex.catches (Right <$> a)-    [ Ex.Handler $ \e -> Ex.throw (e :: Ex.ArithException)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.ArrayException)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.AssertionFailed)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.AsyncException)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.BlockedIndefinitelyOnMVar)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.BlockedIndefinitelyOnSTM)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.Deadlock)-    , Ex.Handler $ \e -> Ex.throw (e ::    Dynamic)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.ErrorCall)-    , Ex.Handler $ \e -> Ex.throw (e ::    ExitCode)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.NestedAtomically)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.NoMethodError)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.NonTermination)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.PatternMatchFail)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.RecConError)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.RecSelError)-    , Ex.Handler $ \e -> Ex.throw (e :: Ex.RecUpdError)-    , Ex.Handler $ return . Left-    ]+syncIO :: MonadIO m => IO a -> ExceptT SomeException m a+syncIO = ExceptT . liftIO . trySync++trySync :: IO a -> IO (Either SomeException a)+trySync io = (fmap Right io) `Exception.catch` \e ->+  case Exception.fromException e of+    Just (Exception.SomeAsyncException _) -> Exception.throwIO e+    Nothing -> return (Left e)
Data/EitherR.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ {-| This module provides 'throwEither' and 'catchEither' for 'Either'.  These two     functions reside here because 'throwEither' and 'catchEither' correspond to 'return'     and ('>>=') for the flipped 'Either' monad: 'EitherR'.  Additionally, this@@ -64,6 +66,8 @@ import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT, throwE, catchE) import Data.Monoid (Monoid(mempty, mappend)) +import qualified Control.Monad.Trans.Except+ {-| If \"@Either e r@\" is the error monad, then \"@EitherR r e@\" is the     corresponding success monad, where: @@ -169,13 +173,18 @@ succeedT :: (Monad m) => r -> ExceptRT r m e succeedT r = ExceptRT (return r) --- | 'catchT' with the arguments flipped+-- | 'catchE' with the arguments flipped handleE :: (Monad m) => (a -> ExceptT b m r) -> ExceptT a m r -> ExceptT b m r handleE = flip catchE  -- | Map a function over the 'Left' value of an 'ExceptT'+#if MIN_VERSION_base(4,8,0)+fmapLT :: Functor m => (a -> b) -> ExceptT a m r -> ExceptT b m r+fmapLT = Control.Monad.Trans.Except.withExceptT+#else fmapLT :: (Monad m) => (a -> b) -> ExceptT a m r -> ExceptT b m r fmapLT f = runExceptRT . fmap f . ExceptRT+#endif  -- | Flip the type variables of an 'ExceptT' flipET :: (Monad m) => ExceptT a m b -> ExceptT b m a
errors.cabal view
@@ -1,7 +1,8 @@ Name: errors-Version: 2.0.1+Version: 2.3.0 Cabal-Version: >=1.8.0.2 Build-Type: Simple+Tested-With: GHC == 7.8.4, GHC == 7.10.2, GHC == 8.0.1 License: BSD3 License-File: LICENSE Copyright: 2012, 2013 Gabriel Gonzalez@@ -16,20 +17,27 @@     This library encourages an error-handling style that directly uses the type     system, rather than out-of-band exceptions. Category: Control, Error Handling+extra-source-files: CHANGELOG.md Source-Repository head     Type: git     Location: https://github.com/Gabriel439/Haskell-Errors-Library  Library     Build-Depends:-        base                >= 4     && < 5  ,-        safe                >= 0.3.3 && < 0.4,-        transformers        >= 0.2   && < 0.5,-        transformers-compat >= 0.4   && < 0.5+        base                >= 4.7   && < 5   ,+        exceptions          >= 0.6   && < 0.11,+        text                            < 1.3 ,+        transformers        >= 0.2   && < 0.6 ,+        transformers-compat >= 0.4   && < 0.7+    if impl(ghc <= 7.6.3)+        Build-Depends:+            safe            >= 0.3.3 && < 0.3.10+    else+        Build-Depends:+            safe            >= 0.3.3 && < 0.4     Exposed-Modules:         Control.Error,         Control.Error.Safe,         Control.Error.Script,         Control.Error.Util,         Data.EitherR-    GHC-Options: -O2