diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for antigen
 
+## 0.3.1.0
+
+* Add `tryZapAntiGen`
+
 ## 0.3.0.0
 
 * Rename `fickle*` to `faulty*`
diff --git a/antigen.cabal b/antigen.cabal
--- a/antigen.cabal
+++ b/antigen.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               antigen
-version:            0.3.0.0
+version:            0.3.1.0
 synopsis:           Fault injection for QuickCheck
 description:
   AntiGen extends QuickCheck to allow injecting random faults into QuickCheck 
@@ -33,7 +33,7 @@
       Test.AntiGen.Internal
     build-depends:    
       base >=4.18 && <5,
-      QuickCheck >= 2.16.0 && < 2.18,
+      QuickCheck >= 2.15.0 && < 2.18,
       free >= 5.2 && < 5.3,
       mtl >= 2.3.1 && < 2.4,
       random >= 1.2 && < 1.4,
diff --git a/src/Test/AntiGen.hs b/src/Test/AntiGen.hs
--- a/src/Test/AntiGen.hs
+++ b/src/Test/AntiGen.hs
@@ -15,6 +15,7 @@
   (||!),
   runAntiGen,
   zapAntiGen,
+  tryZapAntiGen,
 
   -- * AntiGen combinators
   faultyNum,
@@ -43,7 +44,7 @@
   NonZero (..),
   Positive (..),
  )
-import Test.QuickCheck.GenT (MonadGen (..), elements, frequency, listOf1, suchThat)
+import Test.QuickCheck.GenT (MonadGen (..), elements, listOf1, oneof, suchThat)
 
 -- | Returns the provided number.
 -- Negative: returns a value that is not equal to the provided number.
@@ -57,21 +58,13 @@
 
 -- | Generates a value from the first range.
 -- Negative: Generates a value from the second range excluding the first range.
---
--- Note: The second range must not be a subset of the first range!
 antiChoose :: (Integral a, Random a) => (a, a) -> (a, a) -> AntiGen a
-antiChoose rng@(lo, hi) (boundLo, boundHi) =
-  choose rng
-    |! frequency
-      ( mconcat
-          [ [ (fromIntegral $ lo - boundLo, choose rngLo)
-            | lo > boundLo
-            ]
-          , [ (fromIntegral $ boundHi - hi, choose rngHi)
-            | boundHi > hi
-            ]
-          ]
-      )
+antiChoose rng@(lo, hi) (boundLo, boundHi)
+  | lo > boundLo || boundHi > hi =
+      choose rng
+        |! oneof
+          ([choose rngLo | lo > boundLo] <> [choose rngHi | boundHi > hi])
+  | otherwise = choose rng
   where
     rngLo = (boundLo, pred lo)
     rngHi = (succ hi, boundHi)
diff --git a/src/Test/AntiGen/Internal.hs b/src/Test/AntiGen/Internal.hs
--- a/src/Test/AntiGen/Internal.hs
+++ b/src/Test/AntiGen/Internal.hs
@@ -14,6 +14,7 @@
   AntiGen,
   (|!),
   zapAntiGen,
+  tryZapAntiGen,
   runAntiGen,
   evalToPartial,
   evalPartial,
@@ -24,7 +25,7 @@
 import Control.Monad ((<=<))
 import Control.Monad.Free.Church (F (..), MonadFree (..))
 import Control.Monad.Free.Class (wrapT)
-import Control.Monad.State.Strict (MonadState (..), StateT (..), evalStateT, modify)
+import Control.Monad.State.Strict (MonadState (..), StateT (..), evalStateT, modify')
 import Control.Monad.Trans (MonadTrans (..))
 import Test.QuickCheck (Gen, getSize)
 import Test.QuickCheck.GenT (GenT (..), MonadGen (..), runGenT)
@@ -95,7 +96,7 @@
     case dpNegativeGen of
       Just neg -> do
         d <- get
-        modify pred
+        modify' pred
         if d == 0
           then do
             -- Negate the generator
@@ -127,6 +128,15 @@
 -- than `n`.
 zapAntiGen :: Int -> AntiGen a -> Gen a
 zapAntiGen n = fmap evalPartial <$> zapNTimes n <=< evalToPartial
+
+-- | Create a negative generator from an `AntiGen` by introducing at most
+-- `n` mistakes. If there are no decision points, it will return `Nothing`.
+tryZapAntiGen :: Int -> AntiGen a -> Gen (Maybe a)
+tryZapAntiGen n ag = do
+  p <- evalToPartial ag
+  if countDecisionPoints p > 0
+    then Just . evalPartial <$> zapNTimes n p
+    else pure Nothing
 
 -- | Create a positive generator from the provided `AntiGen`.
 runAntiGen :: AntiGen a -> Gen a
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications #-}
 
@@ -5,8 +7,10 @@
 
 import Control.Monad (replicateM)
 import Data.Data (Proxy (..))
+import Data.Word (Word32, Word64)
 import Test.AntiGen (
   AntiGen,
+  antiChooseBounded,
   antiNegative,
   antiNonNegative,
   antiNonPositive,
@@ -20,7 +24,7 @@
   (||!),
  )
 import Test.AntiGen.Internal (countDecisionPoints, evalToPartial)
-import Test.Hspec (Spec, describe, hspec, shouldBe)
+import Test.Hspec (Spec, describe, hspec, shouldBe, shouldSatisfy)
 import Test.Hspec.QuickCheck (prop)
 import Test.QuickCheck (
   Arbitrary (..),
@@ -45,6 +49,7 @@
   (===),
  )
 import Test.QuickCheck.GenT (MonadGen (..), listOf1, oneof)
+import Type.Reflection (Typeable, typeRep)
 
 antiGenPositive :: AntiGen Int
 antiGenPositive = (getPositive @Int <$> arbitrary) |! (getNonPositive <$> arbitrary)
@@ -159,6 +164,12 @@
             )
           ]
 
+chooseBoundedIntegralTest :: forall a. Typeable a => Spec
+chooseBoundedIntegralTest =
+  prop (show (typeRep @a) <> " (0, n)") $ \(Positive (n :: Word64)) -> do
+    res <- zapAntiGen 1 (antiChooseBounded (0, n))
+    pure $ res `shouldSatisfy` (> n)
+
 utilsSpec :: Spec
 utilsSpec =
   describe "utils" $ do
@@ -209,6 +220,10 @@
             [ ("null", null res)
             , ("nonpositive", length (filter (<= 0) res) == 1)
             ]
+    describe "chooseBoundedIntegral" $ do
+      chooseBoundedIntegralTest @Word64
+      chooseBoundedIntegralTest @Word32
+      chooseBoundedIntegralTest @Int
 
 main :: IO ()
 main = hspec $ do
