SafeIO.hs 767 B

12345678910111213141516171819202122232425
  1. {-# LANGUAGE FlexibleContexts #-}
  2. {- |
  3. -}
  4. module Control.Monad.Trans.SafeIO where
  5. import System.IO.Error
  6. import Control.Monad.IO.Class
  7. import Control.Monad.Trans.Class
  8. import Control.Monad.Trans.Either
  9. import Control.Monad.Trans.Control
  10. import qualified Control.Exception.Lifted as Lift
  11. class IOErrorDerivation e where
  12. coerceIOError :: IOError -> e
  13. safeIO :: (MonadIO m, IOErrorDerivation e) => IO a -> EitherT e m a
  14. safeIO io = (liftIO $ tryIOError io) >>= hoistResult
  15. safeCT :: (MonadBaseControl IO m, IOErrorDerivation e) => m a -> EitherT e m a
  16. safeCT f = (lift $ Lift.try f) >>= hoistResult
  17. hoistResult :: (IOErrorDerivation e, Monad m) => Either IOError a -> EitherT e m a
  18. hoistResult (Left e) = left . coerceIOError $ e
  19. hoistResult (Right v) = right v