diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,11 @@
+0.1.1.0
+
+* Add `nfAppIO` and `whnfAppIO` functions, which take a function and its
+  argument separately like `nf`/`whnf`, but whose function returns `IO` like
+  `nfIO`/`whnfIO`. This is useful for benchmarking functions in which the bulk
+  of the work is not bound by IO, but by pure computations that might otherwise
+  be optimized away if the argument is known statically.
+
 0.1.0.0
 
 * This is the first release of `criterion-measurement`. The changelog notes
diff --git a/criterion-measurement.cabal b/criterion-measurement.cabal
--- a/criterion-measurement.cabal
+++ b/criterion-measurement.cabal
@@ -1,5 +1,5 @@
 name:                criterion-measurement
-version:             0.1.0.0
+version:             0.1.1.0
 synopsis:            Criterion measurement functionality and associated types
 description:         Measurement-related functionality extracted from Criterion, with minimal dependencies. The rationale for this is to enable alternative analysis front-ends.
 homepage:            https://github.com/bos/criterion
diff --git a/src/Criterion/Measurement/Types.hs b/src/Criterion/Measurement/Types.hs
--- a/src/Criterion/Measurement/Types.hs
+++ b/src/Criterion/Measurement/Types.hs
@@ -31,7 +31,7 @@
   (
       -- * Benchmark descriptions
       Benchmarkable(..)
-    , Benchmark(..)      
+    , Benchmark(..)
     -- * Measurements
     , Measured(..)
     , fromInt
@@ -58,7 +58,9 @@
     , nf
     , whnf
     , nfIO
-    , whnfIO    
+    , whnfIO
+    , nfAppIO
+    , whnfAppIO
                       )
   where
 
@@ -85,7 +87,7 @@
       , cleanEnv :: Int64 -> a -> IO ()
       , runRepeatedly :: a -> Int64 -> IO ()
       , perRun :: Bool
-      }  
+      }
 
 noop :: Monad m => a -> m ()
 noop = const $ return ()
@@ -274,18 +276,48 @@
 whnf :: (a -> b) -> a -> Benchmarkable
 whnf f x = toBenchmarkable (whnf' f x)
 
--- | Perform an action, then evaluate its result to normal form.
+-- | Perform an action, then evaluate its result to normal form (NF).
 -- This is particularly useful for forcing a lazy 'IO' action to be
 -- completely performed.
+--
+-- If the construction of the 'IO a' value is an important factor
+-- in the benchmark, it is best to use 'nfAppIO' instead.
 nfIO :: NFData a => IO a -> Benchmarkable
 nfIO a = toBenchmarkable (nfIO' rnf a)
 
 -- | Perform an action, then evaluate its result to weak head normal
 -- form (WHNF).  This is useful for forcing an 'IO' action whose result
 -- is an expression to be evaluated down to a more useful value.
+--
+-- If the construction of the 'IO a' value is an important factor
+-- in the benchmark, it is best to use 'whnfAppIO' instead.
 whnfIO :: IO a -> Benchmarkable
 whnfIO a = toBenchmarkable (whnfIO' a)
 
+-- | Apply an argument to a function which performs an action, then
+-- evaluate its result to normal form (NF).
+-- This function constructs the 'IO b' value on each iteration,
+-- similar to 'nf'.
+-- This is particularly useful for 'IO' actions where the bulk of the
+-- work is not bound by IO, but by pure computations that may
+-- optimize away if the argument is known statically, as in 'nfIO'.
+
+-- See issue #189 for more info.
+nfAppIO :: NFData b => (a -> IO b) -> a -> Benchmarkable
+nfAppIO f v = toBenchmarkable (nfAppIO' rnf f v)
+
+-- | Perform an action, then evaluate its result to weak head normal
+-- form (WHNF).
+-- This function constructs the 'IO b' value on each iteration,
+-- similar to 'whnf'.
+-- This is particularly useful for 'IO' actions where the bulk of the
+-- work is not bound by IO, but by pure computations that may
+-- optimize away if the argument is known statically, as in 'nfIO'.
+
+-- See issue #189 for more info.
+whnfAppIO :: (a -> IO b) -> a -> Benchmarkable
+whnfAppIO f v = toBenchmarkable (whnfAppIO' f v)
+
 -- Along with nf' and whnf', the following two functions are the core
 -- benchmarking loops. They have been carefully constructed to avoid
 -- allocation while also evaluating @a@.
@@ -318,6 +350,29 @@
              x <- a
              x `seq` go (n-1)
 {-# NOINLINE whnfIO' #-}
+
+-- | Generate a function which applies an argument to a function a given
+-- number of times, running its action and reducing the result to normal form.
+nfAppIO' :: (b -> ()) -> (a -> IO b) -> a -> (Int64 -> IO ())
+nfAppIO' reduce f v = go
+  where go n
+          | n <= 0    = return ()
+          | otherwise = do
+              x <- f v
+              reduce x `seq` go (n-1)
+{-# NOINLINE nfAppIO' #-}
+
+-- | Generate a function which applies an argument to a function a given
+-- number of times, running its action and reducing the result to
+-- weak-head normal form.
+whnfAppIO' :: (a -> IO b) -> a -> (Int64 -> IO ())
+whnfAppIO' f v = go
+  where go n
+          | n <= 0    = return ()
+          | otherwise = do
+              x <- f v
+              x `seq` go (n-1)
+{-# NOINLINE whnfAppIO' #-}
 
 -- | Specification of a collection of benchmarks and environments. A
 -- benchmark may consist of:
