diff --git a/Control/Monad/Extra.hs b/Control/Monad/Extra.hs
--- a/Control/Monad/Extra.hs
+++ b/Control/Monad/Extra.hs
@@ -1,9 +1,13 @@
+{-# LANGUAGE FlexibleContexts #-}
+
 module Control.Monad.Extra where
 
 import Control.Applicative
 import Control.Monad
-import Control.Monad.Trans.Cont
 import Control.Monad.IO.Class
+import Control.Monad.Trans.Cont
+import Control.Monad.Trans.Control
+import Data.IORef
 
 -- | Synonym for @return ()@.
 skip :: Monad m => m ()
@@ -63,5 +67,119 @@
 io = liftIO
 
 -- | Lift a 'Maybe' value into the 'MaybeT' monad transformer.
-liftMaybe :: (MonadPlus m) => Maybe a -> m a
+liftMaybe :: MonadPlus m => Maybe a -> m a
 liftMaybe = maybe mzero return
+
+-- | Embed a transformer (Kleisli) arrow as an arrow in the base monad
+--   returning a mutated transformer state.  If you do not want the
+--   transformation and your base monad is IO, use 'embedIO'.
+embed :: (MonadBaseControl base m) => (a -> m b) -> m (a -> base (StM m b))
+embed f = control $ \run -> run $ return (run . f)
+
+-- | Return an IO action that closes over the current monad transformer, but
+--   throws away any residual effects within that transformer.
+embedIO :: (MonadBaseControl IO m, MonadIO m) => (a -> m b) -> m (a -> IO b)
+embedIO f = liftBaseWith $ \run -> do
+    result <- newIORef undefined
+    return $ \a -> do
+        _ <- run $ do
+             res <- f a
+             liftIO $ writeIORef result res
+        readIORef result
+
+embedIO2 :: (MonadBaseControl IO m, MonadIO m)
+          => (a -> b -> m r) -> m (a -> b -> IO r)
+embedIO2 f = liftBaseWith $ \run -> do
+    result <- newIORef undefined
+    return $ \a b -> do
+        _ <- run $ do
+             res <- f a b
+             liftIO $ writeIORef result res
+        readIORef result
+
+embedIO3 :: (MonadBaseControl IO m, MonadIO m)
+          => (a -> b -> c -> m r) -> m (a -> b -> c -> IO r)
+embedIO3 f = liftBaseWith $ \run -> do
+    result <- newIORef undefined
+    return $ \a b c -> do
+        _ <- run $ do
+             res <- f a b c
+             liftIO $ writeIORef result res
+        readIORef result
+
+embedIO4 :: (MonadBaseControl IO m, MonadIO m)
+          => (a -> b -> c -> d -> m r) -> m (a -> b -> c -> d -> IO r)
+embedIO4 f = liftBaseWith $ \run -> do
+    result <- newIORef undefined
+    return $ \a b c d -> do
+        _ <- run $ do
+             res <- f a b c d
+             liftIO $ writeIORef result res
+        readIORef result
+
+embedIO5 :: (MonadBaseControl IO m, MonadIO m)
+          => (a -> b -> c -> d -> e -> m r) -> m (a -> b -> c -> d -> e -> IO r)
+embedIO5 f = liftBaseWith $ \run -> do
+    result <- newIORef undefined
+    return $ \a b c d e -> do
+        _ <- run $ do
+             res <- f a b c d e
+             liftIO $ writeIORef result res
+        readIORef result
+
+embedIO6 :: (MonadBaseControl IO m, MonadIO m)
+          => (a -> b -> c -> d -> e -> f -> m r)
+          -> m (a -> b -> c -> d -> e -> f -> IO r)
+embedIO6 x = liftBaseWith $ \run -> do
+    result <- newIORef undefined
+    return $ \a b c d e f -> do
+        _ <- run $ do
+             res <- x a b c d e f
+             liftIO $ writeIORef result res
+        readIORef result
+
+embedIO7 :: (MonadBaseControl IO m, MonadIO m)
+          => (a -> b -> c -> d -> e -> f -> g -> m r)
+          -> m (a -> b -> c -> d -> e -> f -> g -> IO r)
+embedIO7 x = liftBaseWith $ \run -> do
+    result <- newIORef undefined
+    return $ \a b c d e f g -> do
+        _ <- run $ do
+             res <- x a b c d e f g
+             liftIO $ writeIORef result res
+        readIORef result
+
+embedIO8 :: (MonadBaseControl IO m, MonadIO m)
+          => (a -> b -> c -> d -> e -> f -> g -> h -> m r)
+          -> m (a -> b -> c -> d -> e -> f -> g -> h -> IO r)
+embedIO8 x = liftBaseWith $ \run -> do
+    result <- newIORef undefined
+    return $ \a b c d e f g h -> do
+        _ <- run $ do
+             res <- x a b c d e f g h
+             liftIO $ writeIORef result res
+        readIORef result
+
+embedIO9 :: (MonadBaseControl IO m, MonadIO m)
+          => (a -> b -> c -> d -> e -> f -> g -> h -> i -> m r)
+          -> m (a -> b -> c -> d -> e -> f -> g -> h -> i -> IO r)
+embedIO9 x = liftBaseWith $ \run -> do
+    result <- newIORef undefined
+    return $ \a b c d e f g h i -> do
+        _ <- run $ do
+             res <- x a b c d e f g h i
+             liftIO $ writeIORef result res
+        readIORef result
+
+-- | Draw monadic actions from a list until one of them yields a value failing
+--   the predicate, and then return all the passing values in a list within
+--   that monad.
+sequenceUntil :: Monad m => (a -> Bool) -> [m a] -> m [a]
+sequenceUntil _ [] = return []
+sequenceUntil p (m:ms) = do
+    a <- m
+    if p a
+        then return [a]
+        else do
+            as <- sequenceUntil p ms
+            return (a:as)
diff --git a/monad-extras.cabal b/monad-extras.cabal
--- a/monad-extras.cabal
+++ b/monad-extras.cabal
@@ -1,5 +1,5 @@
 name:           monad-extras
-version:        0.4.0.0
+version:        0.5.0
 synopsis:       Extra utility functions for working with monads
 -- description:
 homepage:       http://github.com/jwiegley/monad-extras
@@ -18,4 +18,5 @@
         Control.Monad.Extra
     build-depends:
         base >= 4 && < 5
+      , monad-control
       , transformers
