|
@@ -45,7 +45,9 @@ the EitherT context, you'll have to peel all the other contexts from it first.
|
|
|
module Control.Monad.Trans.SafeIO (
|
|
|
IOErrorDerivation(..),
|
|
|
safeIO,
|
|
|
- safeCT
|
|
|
+ safeCT,
|
|
|
+ hoistResult,
|
|
|
+ liftSuccess
|
|
|
)where
|
|
|
|
|
|
import System.IO.Error
|
|
@@ -63,7 +65,7 @@ class IOErrorDerivation e where
|
|
|
-- | Transforms an IOError on another error type
|
|
|
coerceIOError :: IOError -> e
|
|
|
|
|
|
--- | Safe alternative to liftIO
|
|
|
+-- | Safe alternative to liftIO.
|
|
|
safeIO :: (MonadIO m, IOErrorDerivation e) => IO a -> EitherT e m a
|
|
|
safeIO io = (liftIO $ tryIOError io) >>= hoistResult
|
|
|
|
|
@@ -71,6 +73,17 @@ safeIO io = (liftIO $ tryIOError io) >>= hoistResult
|
|
|
safeCT :: (MonadBaseControl IO m, IOErrorDerivation e) => m a -> EitherT e m a
|
|
|
safeCT f = (lift $ Lift.try f) >>= hoistResult
|
|
|
|
|
|
+-- | Specialized function that hoists a try into the monad.
|
|
|
hoistResult :: (IOErrorDerivation e, Monad m) => Either IOError a -> EitherT e m a
|
|
|
hoistResult (Left e) = left . coerceIOError $ e
|
|
|
hoistResult (Right v) = right v
|
|
|
+
|
|
|
+{- |
|
|
|
+Lifts a function with error handling into a transformed function with
|
|
|
+the same kind of error handling.
|
|
|
+-}
|
|
|
+liftSuccess :: (IOErrorDerivation e, Monad m, MonadTrans t, Monad (t m)) =>
|
|
|
+ EitherT e m a -> EitherT e (t m) a
|
|
|
+liftSuccess f = do
|
|
|
+ r <- lift . lift . runEitherT $ f
|
|
|
+ hoistEither r
|