packages feed

errors 1.3.1 → 1.4.0

raw patch · 6 files changed

+192/−97 lines, 6 filesdep ~basedep ~eitherdep ~safePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, either, safe, transformers

API changes (from Hackage documentation)

+ Control.Error.Util: just :: Monad m => a -> MaybeT m a
+ Control.Error.Util: maybeT :: Monad m => m b -> (a -> m b) -> MaybeT m a -> m b
+ Control.Error.Util: nothing :: Monad m => MaybeT m a
+ Data.EitherR: instance (Monad m, Monoid r) => Alternative (EitherRT r m)
+ Data.EitherR: instance (Monad m, Monoid r) => MonadPlus (EitherRT r m)
+ Data.EitherR: instance MonadIO m => MonadIO (EitherRT r m)
+ Data.EitherR: instance Monoid r => Alternative (EitherR r)
+ Data.EitherR: instance Monoid r => MonadPlus (EitherR r)
- Control.Error.Util: fmapRT :: Functor m => (a -> b) -> EitherT l m a -> EitherT l m b
+ Control.Error.Util: fmapRT :: Monad m => (a -> b) -> EitherT l m a -> EitherT l m b

Files

Control/Error.hs view
@@ -5,8 +5,30 @@ > import Control.Error      This module exports the entire library as well as useful exports from other-    standard error-handling libraries.+    standard error-handling libraries: +    * "Control.Error.Safe": Generalizes the @safe@ library, including 'Either',+      'EitherT', and 'MonadPlus' variations on total functions++    * "Control.Error.Script": Support for simple scripts that catch all errors+      and transform them to 'String's++    * "Control.Error.Util": Utility functions and conversions between common+      error-handling types++    * @Control.Monad.Trans.Either@: The 'EitherT' monad transformer++    * @Control.Monad.Trans.Maybe@: The 'MaybeT' monad transformer++    * @Data.Either@: 'Either' utility functions++    * "Data.EitherR": throw and catch functions, and their corresponding+      \"success\" monads++    * @Data.Maybe@: 'Maybe' utility functions++    * @Safe@: Total versions of partial Prelude functions+     This module does not re-export partial functions from other libraries. -} @@ -25,28 +47,44 @@ import Control.Error.Safe import Control.Error.Script import Control.Error.Util-import Control.Monad.Trans.Either-import Control.Monad.Trans.Maybe-import Data.Either+import Control.Monad.Trans.Either (+    eitherT, bimapEitherT, mapEitherT, hoistEither, left, right )+import Control.Monad.Trans.Maybe (+    mapMaybeT, liftCallCC, liftCatch, liftListen, liftPass )+import Data.Either (either, lefts, rights, partitionEithers) import Data.EitherR-import Data.Maybe hiding (fromJust)-import Safe hiding (-    tailNote,-    initNote,-    headNote,-    lastNote,-    minimumNote,-    maximumNote,-    foldr1Note,-    foldl1Note,-    foldl1Note',-    fromJustNote,-    assertNote,-    at,-    atNote,-    readNote,-    lookupJust,-    lookupJustNote,-    findJust,-    findJustNote,-    abort)+import Data.Maybe (+    maybe,+    isJust,+    isNothing,+    fromMaybe,+    listToMaybe,+    maybeToList,+    catMaybes,+    mapMaybe )+import Safe (+    tailDef,+    tailMay,+    tailSafe,+    initDef,+    initMay,+    initSafe,+    headDef,+    headMay,+    lastDef,+    lastMay,+    minimumDef,+    minimumMay,+    maximumDef,+    maximumMay,+    foldr1Def,+    foldr1May,+    foldl1Def',+    foldl1May',+    fromJustDef,+    atDef,+    atMay,+    readDef,+    readMay,+    lookupJustDef,+    findJustDef )
Control/Error/Safe.hs view
@@ -1,15 +1,22 @@ {-|     This module extends the @safe@ library's functions with corresponding-    versions compatible with 'Either' and 'EitherT', and also provides several+    versions compatible with 'Either' and 'EitherT', and also provides a few     'Maybe'-compatible functions missing from @safe@. -    All functions take an exceptional value to return should they fail.-     I suffix the 'Either'-compatible functions with @Err@ and prefix the     'EitherT'-compatible functions with @try@.      Note that this library re-exports the 'Maybe' compatible functions from     @safe@ in the "Control.Error" module, so they are not provided here.++    The \'@Z@\'-suffixed functions generalize the 'Maybe' functions to also work+    with anything that implements 'MonadPlus', including:++    * Lists++    * Most parsers++    * 'EitherT' (if the left value is a 'Monoid') -}  module Control.Error.Safe (@@ -65,7 +72,7 @@ import Control.Error.Util (note) import Control.Monad (MonadPlus(mzero)) import Control.Monad.Trans.Either (EitherT, hoistEither)-import Safe+import qualified Safe as S  -- | An assertion that fails in the 'Maybe' monad assertMay :: Bool -> Maybe ()@@ -73,51 +80,51 @@  -- | A 'fromRight' that fails in the 'Maybe' monad rightMay :: Either e a -> Maybe a-rightMay = either (\_ -> Nothing) Just+rightMay = rightZ  -- | A 'tail' that fails in the 'Either' monad tailErr :: e -> [a] -> Either e [a]-tailErr e = note e . tailMay+tailErr e = note e . S.tailMay  -- | An 'init' that fails in the 'Either' monad initErr :: e -> [a] -> Either e [a]-initErr e = note e . initMay+initErr e = note e . S.initMay  -- | A 'head' that fails in the 'Either' monad headErr :: e -> [a] -> Either e a-headErr e = note e . headMay+headErr e = note e . S.headMay  -- | A 'last' that fails in the 'Either' monad lastErr :: e -> [a] -> Either e a-lastErr e = note e . lastMay+lastErr e = note e . S.lastMay  -- | A 'minimum' that fails in the 'Either' monad minimumErr :: (Ord a) => e -> [a] -> Either e a-minimumErr e = note e . minimumMay+minimumErr e = note e . S.minimumMay  -- | A 'maximum' that fails in the 'Either' monad maximumErr :: (Ord a) => e -> [a] -> Either e a-maximumErr e = note e . maximumMay+maximumErr e = note e . S.maximumMay  -- | A 'foldr1' that fails in the 'Either' monad foldr1Err :: e -> (a -> a -> a) -> [a] -> Either e a-foldr1Err e step xs = note e $ foldr1May step xs+foldr1Err e step xs = note e $ S.foldr1May step xs  -- | A 'foldl1' that fails in the 'Either' monad foldl1Err :: e -> (a -> a -> a) -> [a] -> Either e a-foldl1Err e step xs = note e $ foldl1May step xs+foldl1Err e step xs = note e $ S.foldl1May step xs  -- | A 'foldl1'' that fails in the 'Either' monad foldl1Err' :: e -> (a -> a -> a) -> [a] -> Either e a-foldl1Err' e step xs = note e $ foldl1May' step xs+foldl1Err' e step xs = note e $ S.foldl1May' step xs  -- | A ('!!') that fails in the 'Either' monad atErr :: e -> [a] -> Int -> Either e a-atErr e xs n = note e $ atMay xs n+atErr e xs n = note e $ S.atMay xs n  -- | A 'read' that fails in the 'Either' monad readErr :: (Read a) => e -> String -> Either e a-readErr e = note e . readMay+readErr e = note e . S.readMay  -- | An assertion that fails in the 'Either' monad assertErr :: e -> Bool -> Either e ()@@ -185,47 +192,47 @@  -- | A 'tail' that fails using 'mzero' tailZ :: (MonadPlus m) => [a] -> m [a]-tailZ = maybe mzero return . tailMay+tailZ = maybe mzero return . S.tailMay  -- | An 'init' that fails using 'mzero' initZ :: (MonadPlus m) => [a] -> m [a]-initZ = maybe mzero return . initMay+initZ = maybe mzero return . S.initMay  -- | A 'head' that fails using 'mzero' headZ :: (MonadPlus m) => [a] -> m a-headZ = maybe mzero return . headMay+headZ = maybe mzero return . S.headMay  -- | A 'last' that fails using 'mzero' lastZ :: (MonadPlus m) => [a] -> m a-lastZ = maybe mzero return . lastMay+lastZ = maybe mzero return . S.lastMay  -- | A 'minimum' that fails using 'mzero' minimumZ :: (MonadPlus m) => (Ord a) => [a] -> m a-minimumZ = maybe mzero return . minimumMay+minimumZ = maybe mzero return . S.minimumMay  -- | A 'maximum' that fails using 'mzero' maximumZ :: (MonadPlus m) => (Ord a) => [a] -> m a-maximumZ = maybe mzero return . maximumMay+maximumZ = maybe mzero return . S.maximumMay  -- | A 'foldr1' that fails using 'mzero' foldr1Z :: (MonadPlus m) => (a -> a -> a) -> [a] -> m a-foldr1Z step xs = maybe mzero return $ foldr1May step xs+foldr1Z step xs = maybe mzero return $ S.foldr1May step xs  -- | A 'foldl1' that fails using 'mzero' foldl1Z :: (MonadPlus m) => (a -> a -> a) -> [a] -> m a-foldl1Z step xs = maybe mzero return $ foldl1May step xs+foldl1Z step xs = maybe mzero return $ S.foldl1May step xs  -- | A 'foldl1'' that fails using 'mzero' foldl1Z' :: (MonadPlus m) => (a -> a -> a) -> [a] -> m a-foldl1Z' step xs = maybe mzero return $ foldl1May' step xs+foldl1Z' step xs = maybe mzero return $ S.foldl1May' step xs  -- | A ('!!') that fails using 'mzero' atZ :: (MonadPlus m) => [a] -> Int -> m a-atZ xs n = maybe mzero return $ atMay xs n+atZ xs n = maybe mzero return $ S.atMay xs n  -- | A 'read' that fails using 'mzero' readZ :: (MonadPlus m) => (Read a) => String -> m a-readZ = maybe mzero return . readMay+readZ = maybe mzero return . S.readMay  -- | An assertion that fails using 'mzero' assertZ :: (MonadPlus m) => Bool -> m ()@@ -237,4 +244,4 @@  -- | A 'fromRight' that fails using 'mzero' rightZ :: (MonadPlus m) => Either e a -> m a-rightZ = either (\_ -> mzero) return+rightZ = either (const mzero) return
Control/Error/Util.hs view
@@ -8,6 +8,10 @@     note,     noteT,     hoistMaybe,+    -- * MaybeT+    maybeT,+    just,+    nothing,     -- * Either     isLeft,     isRight,@@ -39,7 +43,7 @@ -} -- | Suppress the 'Left' value of an 'Either' hush :: Either a b -> Maybe b-hush = either (\_ -> Nothing) Just+hush = either (const Nothing) Just  -- | Suppress the 'Left' value of an 'EitherT' hushT :: (Monad m) => EitherT a m b -> MaybeT m b@@ -57,21 +61,37 @@ hoistMaybe :: (Monad m) => Maybe b -> MaybeT m b hoistMaybe = MaybeT . return +{-| Case analysis for 'MaybeT'++    Use the first argument if the 'MaybeT' computation fails, otherwise apply+    the function to the successful result.+-}+maybeT :: Monad m => m b -> (a -> m b) -> MaybeT m a -> m b+maybeT mb kb (MaybeT ma) = ma >>= maybe mb kb++-- | Analogous to 'Just' and equivalent to 'return'+just :: (Monad m) => a -> MaybeT m a+just a = MaybeT (return (Just a))++-- | Analogous to 'Nothing' and equivalent to 'mzero'+nothing :: (Monad m) => MaybeT m a+nothing = MaybeT (return Nothing)+ -- | Returns whether argument is a 'Left' isLeft :: Either a b -> Bool-isLeft = either (\_ -> True) (\_ -> False)+isLeft = either (const True) (const False)  -- | Returns whether argument is a 'Right' isRight :: Either a b -> Bool-isRight = either (\_ -> False) (\_ -> True)+isRight = either (const False) (const True)  -- | 'fmap' specialized to 'Either', given a name symmetric to 'fmapL' fmapR :: (a -> b) -> Either l a -> Either l b fmapR = fmap  -- | 'fmap' specialized to 'EitherT', given a name symmetric to 'fmapLT'-fmapRT :: (Functor m) => (a -> b) -> EitherT l m a -> EitherT l m b-fmapRT = fmap+fmapRT :: (Monad m) => (a -> b) -> EitherT l m a -> EitherT l m b+fmapRT = liftM  -- | Write a string to standard error err :: String -> IO ()
Data/EitherR.hs view
@@ -1,24 +1,24 @@ {-|-    This modules provides newtypes which flip the type variables of 'Either'-    and 'EitherT' to access the symmetric monad over the opposite type variable.--    This module provides the following simple benefits to the casual user:+    This module provides 'throwE' and 'catchE' for 'Either'.  These two+    functions reside here because 'throwE' and 'catchE' correspond to 'return'+    and ('>>=') for the flipped 'Either' monad: 'EitherR'.  Similarly, this+    module defines 'throwT' and 'catchT' for 'EitherT', which correspond to the+    'Monad' operations for 'EitherRT'. -    * A type-class free alternative to @MonadError@+    These throw and catch functions improve upon @MonadError@ because: -    * No @UndecidableInstances@ or any other extensions, for that matter+    * 'catch' is more general and allows you to change the left value's type -    * A more powerful 'catchE' statement that allows you to change the type of-      error value returned+    * They are Haskell98 -    More advanced users can take advantage of the fact that 'EitherR' and-    'EitherRT' define an entirely symmetric \"success monad\" where-    error-handling computations are the default and successful results terminate-    the monad.  This allows you to chain error-handlers and pass around values-    other than exceptions until you can finally recover from the error:+    More advanced users can use 'EitherR' and 'EitherRT' to program in an+    entirely symmetric \"success monad\" where exceptional results are the norm+    and successful results terminate the computation.  This allows you to chain+    error-handlers using @do@ notation and pass around exceptional values of+    varying types until you can finally recover from the error:  > runEitherRT $ do->     e2 <- ioExceptionHandler e1+>     e2   <- ioExceptionHandler e1 >     bool <- arithmeticExceptionhandler e2 >     when bool $ lift $ putStrLn "DEBUG: Arithmetic handler did something" @@ -54,13 +54,14 @@     flipET,     ) where -import Control.Applicative-import Control.Monad-import Control.Monad.Trans.Class-import Control.Monad.Trans.Either+import Control.Applicative (Applicative(pure, (<*>)), Alternative(empty, (<|>)))+import Control.Monad (liftM, ap, MonadPlus(mzero, mplus))+import Control.Monad.Trans.Class (MonadTrans(lift))+import Control.Monad.IO.Class (MonadIO(liftIO))+import Control.Monad.Trans.Either (EitherT(EitherT, runEitherT), left, right)+import Data.Monoid (Monoid(mempty, mappend)) -{-|-    If \"@Either e r@\" is the error monad, then \"@EitherR r e@\" is the+{-| If \"@Either e r@\" is the error monad, then \"@EitherR r e@\" is the     corresponding success monad, where:      * 'return' is 'throwE'.@@ -79,22 +80,33 @@     (<*>) = ap  instance Monad (EitherR r) where-    return = EitherR . Left-    (EitherR m) >>= f = EitherR $ case m of-        Left  e -> runEitherR (f e)-        Right r -> Right r+    return e = EitherR (Left e)+    EitherR m >>= f = case m of+        Left  e -> f e+        Right r -> EitherR (Right r) +instance (Monoid r) => Alternative (EitherR r) where+    empty = EitherR (Right mempty)+    e1@(EitherR (Left _)) <|> _ = e1+    _ <|> e2@(EitherR (Left _)) = e2+    EitherR (Right r1) <|> EitherR (Right r2)+        = EitherR (Right (mappend r1 r2))++instance (Monoid r) => MonadPlus (EitherR r) where+    mzero = empty+    mplus = (<|>)+ -- | Complete error handling, returning a result succeed :: r -> EitherR r e-succeed = EitherR . return+succeed r = EitherR (return r)  -- | 'throwE' in the error monad corresponds to 'return' in the success monad throwE :: e -> Either e r-throwE = runEitherR . return+throwE e = runEitherR (return e)  -- | 'catchE' in the error monad corresponds to ('>>=') in the success monad catchE :: Either a r -> (a -> Either b r) -> Either b r-e `catchE` f = runEitherR $ (EitherR e) >>= (EitherR . f)+e `catchE` f = runEitherR $ EitherR e >>= \a -> EitherR (f a)  -- | 'catchE' with the arguments flipped handleE :: (a -> Either b r) -> Either a r -> Either b r@@ -121,27 +133,46 @@     (<*>) = ap  instance (Monad m) => Monad (EitherRT r m) where-    return = EitherRT . left+    return e = EitherRT (left e)     m >>= f = EitherRT $ EitherT $ do         x <- runEitherT $ runEitherRT m         runEitherT $ runEitherRT $ case x of             Left  e -> f e-            Right r -> succeedT r+            Right r -> EitherRT (right r) +instance (Monad m, Monoid r) => Alternative (EitherRT r m) where+    empty = EitherRT $ EitherT $ return $ Right mempty+    e1 <|> e2 = EitherRT $ EitherT $ do+        x1 <- runEitherT $ runEitherRT e1+        case x1 of+            Left  l  -> return (Left l)+            Right r1 -> do+                x2 <- runEitherT $ runEitherRT e2+                case x2 of+                    Left  l  -> return (Left l)+                    Right r2 -> return (Right (mappend r1 r2))++instance (Monad m, Monoid r) => MonadPlus (EitherRT r m) where+    mzero = empty+    mplus = (<|>)+ instance MonadTrans (EitherRT r) where     lift = EitherRT . EitherT . liftM Left +instance (MonadIO m) => MonadIO (EitherRT r m) where+    liftIO = lift . liftIO+ -- | Complete error handling, returning a result succeedT :: (Monad m) => r -> EitherRT r m e-succeedT = EitherRT . return+succeedT r = EitherRT (return r)  -- | 'throwT' in the error monad corresponds to 'return' in the success monad throwT :: (Monad m) => e -> EitherT e m r-throwT = runEitherRT . return+throwT e = runEitherRT (return e)  -- | 'catchT' in the error monad corresponds to ('>>=') in the success monad catchT :: (Monad m) => EitherT a m r -> (a -> EitherT b m r) -> EitherT b m r-e `catchT` f = runEitherRT $ (EitherRT e) >>= (EitherRT . f)+e `catchT` f = runEitherRT $ EitherRT e >>= \a -> EitherRT (f a)  -- | 'catchT' with the arguments flipped handleT :: (Monad m) => (a -> EitherT b m r) -> EitherT a m r -> EitherT b m r
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2012, Gabriel Gonzalez+Copyright (c) 2012, 2013, Gabriel Gonzalez All rights reserved.  Redistribution and use in source and binary forms, with or without modification,
errors.cabal view
@@ -1,13 +1,12 @@ Name: errors-Version: 1.3.1+Version: 1.4.0 Cabal-Version: >=1.8.0.2 Build-Type: Simple License: BSD3 License-File: LICENSE-Copyright: 2012 Gabriel Gonzalez+Copyright: 2012, 2013 Gabriel Gonzalez Author: Gabriel Gonzalez Maintainer: Gabriel439@gmail.com-Stability: Experimental Bug-Reports: https://github.com/Gabriel439/Haskell-Errors-Library/issues Synopsis: Simplified error-handling Description:@@ -25,9 +24,9 @@ Library     Build-Depends:         base >= 4 && < 5,-        either >= 3.0.1,-        safe >= 0.3.3,-        transformers >= 0.2+        either >= 3.1 && < 3.5,+        safe >= 0.3.3 && < 0.4,+        transformers >= 0.2 && < 0.4     Exposed-Modules:         Control.Error,         Control.Error.Safe,