Browse Source

SafeIO: Added lifiting and state management functions

Marcos Dumay de Medeiros 7 years ago
parent
commit
1f29a90088
1 changed files with 15 additions and 2 deletions
  1. 15 2
      src/Control/Monad/Trans/SafeIO.hs

+ 15 - 2
src/Control/Monad/Trans/SafeIO.hs

@@ -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