diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,13 @@
 # ChangeLog for unliftio-core
 
+## 0.2.1.0
+
+* Added `Control.Monad.IO.Unlift.liftIOOp`
+
+## 0.2.0.2
+
+* Widen `base` upperbound to `< 4.17` to support ghc-9.2.
+
 ## 0.2.0.1
 
 * Remove faulty default implementation of `withRunInIO` [#56](https://github.com/fpco/unliftio/issues/56)
diff --git a/src/Control/Monad/IO/Unlift.hs b/src/Control/Monad/IO/Unlift.hs
--- a/src/Control/Monad/IO/Unlift.hs
+++ b/src/Control/Monad/IO/Unlift.hs
@@ -9,6 +9,7 @@
   , withUnliftIO
   , toIO
   , wrappedWithRunInIO
+  , liftIOOp
   , MonadIO (..)
   ) where
 
@@ -35,21 +36,31 @@
 -- 'MonadUnliftIO' to 'ReaderT' and 'IdentityT' transformers on top of
 -- 'IO'.
 --
--- Laws. For any value @u@ returned by 'askUnliftIO', it must meet the
+-- Laws. For any function @run@ provided by 'withRunInIO', it must meet the
 -- monad transformer laws as reformulated for @MonadUnliftIO@:
 --
--- * @unliftIO u . return = return@
+-- * @run . return = return@
 --
--- * @unliftIO u (m >>= f) = unliftIO u m >>= unliftIO u . f@
+-- * @run (m >>= f) = run m >>= run . f@
 --
--- Instances of @MonadUnliftIO@ must also satisfy the idempotency law:
+-- Instances of @MonadUnliftIO@ must also satisfy the following laws:
 --
--- * @askUnliftIO >>= \\u -> (liftIO . unliftIO u) m = m@
+-- [Identity law] @withRunInIO (\\run -> run m) = m@
+-- [Inverse law]  @withRunInIO (\\_ -> m) = liftIO m@
 --
--- This law showcases two properties. First, 'askUnliftIO' doesn't change
--- the monadic context, and second, @liftIO . unliftIO u@ is equivalent to
--- @id@ IF called in the same monadic context as 'askUnliftIO'.
+-- As an example of an invalid instance, a naive implementation of
+-- @MonadUnliftIO (StateT s m)@ might be
 --
+-- @
+-- withRunInIO inner =
+--   StateT $ \\s ->
+--     withRunInIO $ \\run ->
+--       inner (run . flip evalStateT s)
+-- @
+--
+-- This breaks the identity law because the inner @run m@ would throw away
+-- any state changes in @m@.
+--
 -- @since 0.1.0.0
 class MonadIO m => MonadUnliftIO m where
   -- | Convenience function for capturing the monadic context and running an 'IO'
@@ -58,9 +69,11 @@
   --
   -- @since 0.1.0.0
   withRunInIO :: ((forall a. m a -> IO a) -> IO b) -> m b
+
 instance MonadUnliftIO IO where
   {-# INLINE withRunInIO #-}
   withRunInIO inner = inner id
+
 instance MonadUnliftIO m => MonadUnliftIO (ReaderT r m) where
   {-# INLINE withRunInIO #-}
   withRunInIO inner =
@@ -124,13 +137,16 @@
 Useful for the common case where you want to simply delegate to the
 underlying transformer.
 
+Note: You can derive 'MonadUnliftIO' for newtypes without this helper function
+in @unliftio-core@ 0.2.0.0 and later.
+
 @since 0.1.2.0
 ==== __Example__
 
 > newtype AppT m a = AppT { unAppT :: ReaderT Int (ResourceT m) a }
 >   deriving (Functor, Applicative, Monad, MonadIO)
->   -- Unfortunately, deriving MonadUnliftIO does not work.
 >
+> -- Same as `deriving newtype (MonadUnliftIO)`
 > instance MonadUnliftIO m => MonadUnliftIO (AppT m) where
 >   withRunInIO = wrappedWithRunInIO AppT unAppT
 -}
@@ -145,3 +161,17 @@
                    -> m b
 wrappedWithRunInIO wrap unwrap inner = wrap $ withRunInIO $ \run ->
   inner $ run . unwrap
+
+{- | A helper function for lifting @IO a -> IO b@ functions into any @MonadUnliftIO@.
+
+=== __Example__
+
+> liftedTry :: (Exception e, MonadUnliftIO m) => m a -> m (Either e a)
+> liftedTry m = liftIOOp Control.Exception.try m
+
+@since 0.2.1.0
+-}
+liftIOOp :: MonadUnliftIO m => (IO a -> IO b) -> m a -> m b
+liftIOOp f x = do
+  runInIO <- askRunInIO
+  liftIO $ f $ runInIO x
diff --git a/unliftio-core.cabal b/unliftio-core.cabal
--- a/unliftio-core.cabal
+++ b/unliftio-core.cabal
@@ -1,13 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.33.0.
+-- This file has been generated from package.yaml by hpack version 0.35.1.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 9cae5ca1af8760786d8e586fd9b1ed7e329f13f4ec8a3d0aee62818b25038c1f
 
 name:           unliftio-core
-version:        0.2.0.1
+version:        0.2.1.0
 synopsis:       The MonadUnliftIO typeclass for unlifting monads to IO
 description:    Please see the documentation and README at <https://www.stackage.org/package/unliftio-core>
 category:       Control
@@ -30,6 +28,6 @@
   hs-source-dirs:
       src
   build-depends:
-      base >=4.5 && <4.14
-    , transformers >=0.2 && <0.6
+      base >=4.9 && <4.17
+    , transformers >=0.2 && <0.7
   default-language: Haskell2010
