aboutsummaryrefslogtreecommitdiff
path: root/src/Rahm/Desktop/Common.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Rahm/Desktop/Common.hs')
-rw-r--r--src/Rahm/Desktop/Common.hs21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/Rahm/Desktop/Common.hs b/src/Rahm/Desktop/Common.hs
index 6ca3513..f436239 100644
--- a/src/Rahm/Desktop/Common.hs
+++ b/src/Rahm/Desktop/Common.hs
@@ -29,6 +29,7 @@ where
import Control.Applicative ((<*))
import Control.Exception (SomeException (SomeException), catch)
import Control.Monad (forM_, guard, void, when)
+import Control.Monad.Except (MonadError (catchError, throwError))
import Control.Monad.Trans.Class
import Control.Monad.Trans.Except (ExceptT (..), catchE, runExceptT, throwE)
import Control.Monad.Trans.Identity (IdentityT (..))
@@ -253,8 +254,26 @@ floatAll ws = do
windows endo
-class (Monad m) => Xish m where
+class Xish m where
liftFromX :: X a -> m a
+ finallyX :: m a -> m () -> m a
instance Xish X where
liftFromX = id
+ finallyX mt err = do
+ maybe (fail "original action failed.") (\a -> err >> return a)
+ =<< catchX (Just <$> mt) (return Nothing)
+
+instance Xish (MaybeT X) where
+ liftFromX = lift
+ finallyX mt err = MaybeT $ do
+ maybeR <- runMaybeT mt
+ case maybeR of
+ Nothing -> runMaybeT err >> return Nothing
+ Just r -> fmap (r <$) (runMaybeT err)
+
+instance Xish (ExceptT e X) where
+ liftFromX = lift
+ finallyX mt err = do
+ either (\e -> err >> throwError e) (\a -> err >> return a)
+ =<< catchError (Right <$> mt) (return . Left)