diff --git a/Control/Error.hs b/Control/Error.hs
--- a/Control/Error.hs
+++ b/Control/Error.hs
@@ -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 )
diff --git a/Control/Error/Safe.hs b/Control/Error/Safe.hs
--- a/Control/Error/Safe.hs
+++ b/Control/Error/Safe.hs
@@ -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
diff --git a/Control/Error/Util.hs b/Control/Error/Util.hs
--- a/Control/Error/Util.hs
+++ b/Control/Error/Util.hs
@@ -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 ()
diff --git a/Data/EitherR.hs b/Data/EitherR.hs
--- a/Data/EitherR.hs
+++ b/Data/EitherR.hs
@@ -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
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -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,
diff --git a/errors.cabal b/errors.cabal
--- a/errors.cabal
+++ b/errors.cabal
@@ -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,
