diff --git a/Control/Error.hs b/Control/Error.hs
--- a/Control/Error.hs
+++ b/Control/Error.hs
@@ -6,11 +6,13 @@
 
     This module exports the entire library as well as useful exports from other
     standard error-handling libraries.
+
+    This module does not re-export partial functions from other libraries.
 -}
 
 module Control.Error (
-    module Control.Error.Script,
     module Control.Error.Safe,
+    module Control.Error.Script,
     module Control.Error.Util,
     module Control.Monad.Trans.Either,
     module Control.Monad.Trans.Maybe,
@@ -20,12 +22,31 @@
     module Safe
     ) where
 
-import Control.Error.Script
 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 Data.EitherR
-import Data.Maybe
-import Safe
+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)
diff --git a/Control/Error/Safe.hs b/Control/Error/Safe.hs
--- a/Control/Error/Safe.hs
+++ b/Control/Error/Safe.hs
@@ -1,6 +1,7 @@
 {-|
     This module extends the @safe@ library's functions with corresponding
-    versions compatible with 'Either' and 'EitherT'.
+    versions compatible with 'Either' and 'EitherT', and also provides several
+    'Maybe'-compatible functions missing from @safe@.
 
     All functions take an exceptional value to return should they fail.
 
@@ -12,6 +13,9 @@
 -}
 
 module Control.Error.Safe (
+    -- * Maybe-compatible functions
+    assertMay,
+    rightMay,
     -- * Either-compatible functions
     tailErr,
     initErr,
@@ -25,6 +29,7 @@
     atErr,
     readErr,
     assertErr,
+    justErr,
     -- * EitherT-compatible functions
     tryTail,
     tryInit,
@@ -38,12 +43,38 @@
     tryAt,
     tryRead,
     tryAssert,
+    tryJust,
+    tryRight,
+    -- * MonadPlus-compatible functions
+    tailZ,
+    initZ,
+    headZ,
+    lastZ,
+    minimumZ,
+    maximumZ,
+    foldr1Z,
+    foldl1Z,
+    foldl1Z',
+    atZ,
+    readZ,
+    assertZ,
+    justZ,
+    rightZ
     ) where
 
-import Control.Error.Util
-import Control.Monad.Trans.Either
+import Control.Error.Util (note)
+import Control.Monad (MonadPlus(mzero))
+import Control.Monad.Trans.Either (EitherT, hoistEither)
 import Safe
 
+-- | An assertion that fails in the 'Maybe' monad
+assertMay :: Bool -> Maybe ()
+assertMay = assertZ
+
+-- | A 'fromRight' that fails in the 'Maybe' monad
+rightMay :: Either e a -> Maybe a
+rightMay = either (\_ -> Nothing) Just
+
 -- | A 'tail' that fails in the 'Either' monad
 tailErr :: e -> [a] -> Either e [a]
 tailErr e = note e . tailMay
@@ -89,53 +120,121 @@
 readErr e = note e . readMay
 
 -- | An assertion that fails in the 'Either' monad
-assertErr :: e -> Bool -> a -> Either e a
-assertErr e p a = if p then Right a else Left e
+assertErr :: e -> Bool -> Either e ()
+assertErr e p = if p then Right () else Left e
 
+-- | A 'fromJust' that fails in the 'Either' monad
+justErr :: e -> Maybe a -> Either e a
+justErr e = maybe (Left e) Right
+
 -- | A 'tail' that fails in the 'EitherT' monad
 tryTail :: (Monad m) => e -> [a] -> EitherT e m [a]
-tryTail e xs = liftEither $ tailErr e xs
+tryTail e xs = hoistEither $ tailErr e xs
 
 -- | An 'init' that fails in the 'EitherT' monad
 tryInit :: (Monad m) => e -> [a] -> EitherT e m [a]
-tryInit e xs = liftEither $ initErr e xs
+tryInit e xs = hoistEither $ initErr e xs
 
 -- | A 'head' that fails in the 'EitherT' monad
 tryHead :: (Monad m) => e -> [a] -> EitherT e m a
-tryHead e xs = liftEither $ headErr e xs
+tryHead e xs = hoistEither $ headErr e xs
 
 -- | A 'last' that fails in the 'EitherT' monad
 tryLast :: (Monad m) => e -> [a] -> EitherT e m a
-tryLast e xs = liftEither $ lastErr e xs
+tryLast e xs = hoistEither $ lastErr e xs
 
 -- | A 'minimum' that fails in the 'EitherT' monad
 tryMinimum :: (Monad m, Ord a) => e -> [a] -> EitherT e m a
-tryMinimum e xs = liftEither $ maximumErr e xs
+tryMinimum e xs = hoistEither $ maximumErr e xs
 
 -- | A 'maximum' that fails in the 'EitherT' monad
 tryMaximum :: (Monad m, Ord a) => e -> [a] -> EitherT e m a
-tryMaximum e xs = liftEither $ maximumErr e xs
+tryMaximum e xs = hoistEither $ maximumErr e xs
 
 -- | A 'foldr1' that fails in the 'EitherT' monad
 tryFoldr1 :: (Monad m) => e -> (a -> a -> a) -> [a] -> EitherT e m a
-tryFoldr1 e step xs = liftEither $ foldr1Err e step xs
+tryFoldr1 e step xs = hoistEither $ foldr1Err e step xs
 
 -- | A 'foldl1' that fails in the 'EitherT' monad
 tryFoldl1 :: (Monad m) => e -> (a -> a -> a) -> [a] -> EitherT e m a
-tryFoldl1 e step xs = liftEither $ foldl1Err e step xs
+tryFoldl1 e step xs = hoistEither $ foldl1Err e step xs
 
 -- | A 'foldl1'' that fails in the 'EitherT' monad
 tryFoldl1' :: (Monad m) => e -> (a -> a -> a) -> [a] -> EitherT e m a
-tryFoldl1' e step xs = liftEither $ foldl1Err' e step xs
+tryFoldl1' e step xs = hoistEither $ foldl1Err' e step xs
 
 -- | A ('!!') that fails in the 'EitherT' monad
 tryAt :: (Monad m) => e -> [a] -> Int -> EitherT e m a
-tryAt e xs n = liftEither $ atErr e xs n
+tryAt e xs n = hoistEither $ atErr e xs n
 
 -- | A 'read' that fails in the 'EitherT' monad
 tryRead :: (Monad m, Read a) => e -> String -> EitherT e m a
-tryRead e str = liftEither $ readErr e str
+tryRead e str = hoistEither $ readErr e str
 
 -- | An assertion that fails in the 'EitherT' monad
-tryAssert :: (Monad m) => e -> Bool -> a -> EitherT e m a
-tryAssert e p a = liftEither $ assertErr e p a
+tryAssert :: (Monad m) => e -> Bool -> EitherT e m ()
+tryAssert e p = hoistEither $ assertErr e p
+
+-- | A 'fromJust' that fails in the 'EitherT' monad
+tryJust :: (Monad m) => e -> Maybe a -> EitherT e m a
+tryJust e m = hoistEither $ justErr e m
+
+-- | A 'fromRight' that fails in the 'EitherT' monad
+tryRight :: (Monad m) => Either e a -> EitherT e m a
+tryRight = hoistEither
+
+-- | A 'tail' that fails using 'mzero'
+tailZ :: (MonadPlus m) => [a] -> m [a]
+tailZ = maybe mzero return . tailMay
+
+-- | An 'init' that fails using 'mzero'
+initZ :: (MonadPlus m) => [a] -> m [a]
+initZ = maybe mzero return . initMay
+
+-- | A 'head' that fails using 'mzero'
+headZ :: (MonadPlus m) => [a] -> m a
+headZ = maybe mzero return . headMay
+
+-- | A 'last' that fails using 'mzero'
+lastZ :: (MonadPlus m) => [a] -> m a
+lastZ = maybe mzero return . lastMay
+
+-- | A 'minimum' that fails using 'mzero'
+minimumZ :: (MonadPlus m) => (Ord a) => [a] -> m a
+minimumZ = maybe mzero return . minimumMay
+
+-- | A 'maximum' that fails using 'mzero'
+maximumZ :: (MonadPlus m) => (Ord a) => [a] -> m a
+maximumZ = maybe mzero return . 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
+
+-- | A 'foldl1' that fails using 'mzero'
+foldl1Z :: (MonadPlus m) => (a -> a -> a) -> [a] -> m a
+foldl1Z step xs = maybe mzero return $ 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
+
+-- | A ('!!') that fails using 'mzero'
+atZ :: (MonadPlus m) => [a] -> Int -> m a
+atZ xs n = maybe mzero return $ atMay xs n
+
+-- | A 'read' that fails using 'mzero'
+readZ :: (MonadPlus m) => (Read a) => String -> m a
+readZ = maybe mzero return . readMay
+
+-- | An assertion that fails using 'mzero'
+assertZ :: (MonadPlus m) => Bool -> m ()
+assertZ p = if p then return () else mzero
+
+-- | A 'fromJust' that fails using 'mzero'
+justZ :: (MonadPlus m) => Maybe a -> m a
+justZ = maybe mzero return
+
+-- | A 'fromRight' that fails using 'mzero'
+rightZ :: (MonadPlus m) => Either e a -> m a
+rightZ = either (\_ -> mzero) return
diff --git a/Control/Error/Script.hs b/Control/Error/Script.hs
--- a/Control/Error/Script.hs
+++ b/Control/Error/Script.hs
@@ -1,31 +1,35 @@
 {-|
-    Use this module if you like to write simple scripts, but you prefer to use
-    'EitherT' to handle errors rather than @Control.Exception@.
+    Use this module if you like to write simple scripts with 'String'-based
+    errors, but you prefer to use 'EitherT' to handle errors rather than
+    @Control.Exception@.
 
 > import Control.Error
 >
 > main = runScript $ do
->     str <- tryIO getLine
+>     str <- scriptIO getLine
 >     n   <- tryRead "Read failed" str
->     tryIO $ print (n + 1)
+>     scriptIO $ print (n + 1)
 -}
 
 module Control.Error.Script (
     -- * The Script Monad
     Script,
     runScript,
-    tryMaybe,
-    tryEither,
-    tryIO
+    scriptIO
     ) where
 
-import Control.Exception
-import Control.Monad.Trans.Either
-import Control.Error.Util
-import Data.EitherR
-import System.IO
-import System.Exit
+import Control.Exception (try, SomeException)
+import Control.Monad (liftM)
+import Control.Monad.IO.Class (MonadIO(liftIO))
+import Control.Monad.Trans.Either (EitherT(EitherT, runEitherT))
+import Control.Error.Util (errLn)
+import Data.EitherR (fmapL)
+import System.Exit (exitFailure)
 
+-- Documentation
+import Control.Monad.Trans.Class (lift)
+import System.IO (stderr)
+
 -- | An 'IO' action that can fail with a 'String' error message
 type Script = EitherT String IO
 
@@ -39,19 +43,18 @@
     e <- runEitherT s
     case e of
         Left  e -> do
-            hPutStrLn stderr e
+            errLn e
             exitFailure
         Right a -> return a
 
--- | A 'Maybe' that fails in the 'Script' monad
-tryMaybe :: String -> Maybe a -> Script a
-tryMaybe str = tryEither . note str
-
--- | An 'Either' that fails in the 'Script' monad
-tryEither :: Either String r -> Script r
-tryEither = liftEither
+{-|
+    'scriptIO' resembles 'lift', except it catches all exceptions and converts
+    them to 'String's.
 
--- | 'tryIO' is like 'lift', except it converts exceptions to the 'Script' monad
-tryIO :: IO a -> Script a
-tryIO io = EitherT . fmap (fmapL show)
-                   $ (try :: IO a -> IO (Either SomeException a)) io
+    Note that 'scriptIO' is compatible with the 'Script' monad.
+-}
+scriptIO :: (MonadIO m) => IO a -> EitherT String m a
+scriptIO = EitherT
+         . liftIO
+         . liftM (fmapL show)
+         . (try :: IO a -> IO (Either SomeException a))
diff --git a/Control/Error/Util.hs b/Control/Error/Util.hs
--- a/Control/Error/Util.hs
+++ b/Control/Error/Util.hs
@@ -1,19 +1,45 @@
-{-|
-    Use this module to convert between 'Maybe', 'Either', 'MaybeT', and
-    'EitherT'.
--}
+-- | This module exports miscellaneous error-handling functions.
 
-module Control.Error.Util where
+module Control.Error.Util (
+    -- * Conversion
+    -- $conversion
+    hush,
+    hushT,
+    note,
+    noteT,
+    hoistMaybe,
+    -- * Either
+    isLeft,
+    isRight,
+    fmapR,
+    -- * EitherT
+    fmapRT,
+    -- * Error Reporting
+    err,
+    errLn,
+    -- * Exceptions
+    tryIO
+    ) where
 
-import Control.Monad
-import Control.Monad.Trans.Either
-import Control.Monad.Trans.Maybe
+import Control.Exception (try, IOException)
+import Control.Monad (liftM)
+import Control.Monad.IO.Class (MonadIO(liftIO))
+import Control.Monad.Trans.Either (EitherT(EitherT, runEitherT))
+import Control.Monad.Trans.Maybe (MaybeT(MaybeT, runMaybeT))
+import System.IO (hPutStr, hPutStrLn, stderr)
 
+-- For Documentation
+import Data.EitherR (fmapL, fmapLT)
+
+{- $conversion
+    Use these functions to convert between 'Maybe', 'Either', 'MaybeT', and
+    'EitherT'.
+
+    Note that 'hoistEither' is provided by the @either@ package.
+-}
 -- | Suppress the 'Left' value of an 'Either'
 hush :: Either a b -> Maybe b
-hush e = case e of
-    Left  _ -> Nothing
-    Right b -> Just b
+hush = either (\_ -> Nothing) Just
 
 -- | Suppress the 'Left' value of an 'EitherT'
 hushT :: (Monad m) => EitherT a m b -> MaybeT m b
@@ -21,18 +47,40 @@
 
 -- | Tag the 'Nothing' value of a 'Maybe'
 note :: a -> Maybe b -> Either a b
-note a m = case m of
-    Nothing -> Left  a
-    Just b  -> Right b
+note a = maybe (Left a) Right
 
 -- | Tag the 'Nothing' value of a 'MaybeT'
 noteT :: (Monad m) => a -> MaybeT m b -> EitherT a m b
 noteT a = EitherT . liftM (note a) . runMaybeT
 
 -- | Lift a 'Maybe' to the 'MaybeT' monad
-liftMaybe :: (Monad m) => Maybe b -> MaybeT m b
-liftMaybe = MaybeT . return
+hoistMaybe :: (Monad m) => Maybe b -> MaybeT m b
+hoistMaybe = MaybeT . return
 
--- | Lift an 'Either' to the 'EitherT' monad
-liftEither :: (Monad m) => Either a b -> EitherT a m b
-liftEither = EitherT . return
+-- | Returns whether argument is a 'Left'
+isLeft :: Either a b -> Bool
+isLeft = either (\_ -> True) (\_ -> False)
+
+-- | Returns whether argument is a 'Right'
+isRight :: Either a b -> Bool
+isRight = either (\_ -> False) (\_ -> 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
+
+-- | Write a string to standard error
+err :: String -> IO ()
+err = hPutStr stderr
+
+-- | Write a string with a newline to standard error
+errLn :: String -> IO ()
+errLn = hPutStrLn stderr
+
+-- | Catch 'IOException's and convert them to the 'EitherT' monad
+tryIO :: (MonadIO m) => IO a -> EitherT IOException m a
+tryIO = EitherT . liftIO . try
diff --git a/Data/EitherR.hs b/Data/EitherR.hs
--- a/Data/EitherR.hs
+++ b/Data/EitherR.hs
@@ -23,9 +23,14 @@
 >     when bool $ lift $ putStrLn "DEBUG: Arithmetic handler did something"
 
     If any of the above error handlers 'succeed', no other handlers are tried.
+
+    If you choose not to typefully distinguish between the error and sucess
+    monad, then use 'flipE' and 'flipET', which swap the type variables without
+    changing the type.
 -}
 
 module Data.EitherR (
+    -- * EitherR
     EitherR(..),
     -- ** Operations in the EitherR monad
     succeed,
@@ -34,6 +39,8 @@
     catchE,
     handleE,
     fmapL,
+    -- ** Flip alternative
+    flipE,
     -- * EitherRT
     EitherRT(..),
     -- ** Operations in the EitherRT monad
@@ -42,7 +49,9 @@
     throwT,
     catchT,
     handleT,
-    fmapLT
+    fmapLT,
+    -- ** Flip alternative
+    flipET,
     ) where
 
 import Control.Applicative
@@ -95,6 +104,12 @@
 fmapL :: (a -> b) -> Either a r -> Either b r
 fmapL f = runEitherR . fmap f . EitherR
 
+-- | Flip the type variables of 'Either'
+flipE :: Either a b -> Either b a
+flipE e = case e of
+    Left  a -> Right a
+    Right b -> Left  b
+
 -- | 'EitherR' converted into a monad transformer
 newtype EitherRT r m e = EitherRT { runEitherRT :: EitherT e m r }
 
@@ -135,3 +150,7 @@
 -- | Map a function over the 'Left' value of an 'EitherT'
 fmapLT :: (Monad m) => (a -> b) -> EitherT a m r -> EitherT b m r
 fmapLT f = runEitherRT . fmap f . EitherRT
+
+-- | Flip the type variables of an 'EitherT'
+flipET :: (Monad m) => EitherT a m b -> EitherT b m a
+flipET = EitherT . liftM flipE . runEitherT
diff --git a/errors.cabal b/errors.cabal
--- a/errors.cabal
+++ b/errors.cabal
@@ -1,6 +1,6 @@
 Name: errors
-Version: 1.2.1
-Cabal-Version: >=1.14.0
+Version: 1.3.0
+Cabal-Version: >=1.8.0.2
 Build-Type: Simple
 License: BSD3
 License-File: LICENSE
@@ -23,12 +23,15 @@
     Location: https://github.com/Gabriel439/Haskell-Errors-Library
 
 Library
-    Build-Depends: base >= 4 && < 5, either >= 3.0.1, safe, transformers
+    Build-Depends:
+        base >= 4 && < 5,
+        either >= 3.0.1,
+        safe >= 0.3.3,
+        transformers >= 0.3.0.0
     Exposed-Modules:
         Control.Error,
+        Control.Error.Safe,
         Control.Error.Script,
         Control.Error.Util,
-        Control.Error.Safe,
         Data.EitherR
     GHC-Options: -O2
-    Default-Language: Haskell2010
