diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## Version 1.3 (2023-06-22)
+
+* Better documentation for `Var` ([#491][491], [@endgame][endgame])
+* Bump upper bounds for `ansi-terminal` ([#486][486], [@mpilgrem][mpilgrem])
+* Better documentation for `Gen.filter[T]`, `Gen.mapMaybe[T]`, `Tree.prune` ([#485][485], [@ChickenProp][ChickenProp])
+* Update Github CI actions, exclude Haddocks for old GHCs ([#482][482], [@ysangkok][ysangkok])
+* Support GHC 9.6 ([#481][481], [@ysangkok][ysangkok])
+* Bump upper bounds for `resourcet` and `primitive` ([#478][478], [@shlevy][shlevy])
+* Export `Hedgehog.Internal.Seed.seed` ([#477][477], [@sol][sol])
+* Better documentation for `sample` ([#468][468], [@parsonsmatt][parsonsmatt])
+* Replace exceptions dependency with safe-exceptions ([#466][466], [@ocharles][ocharles])
+* Generalise `Hedgehog.Gen.element` ([#411](411), [@ocharles][ocharles])
+
 ## Version 1.2 (2022-08-28)
 
 * Allow skipping to a specific test number or shrink result ([#454][454], [@ChickenProp][ChickenProp])
@@ -8,6 +21,11 @@
 * Add example for Gen.subsequence ([#450][450], [@chris-martin][chris-martin])
 * Don't drop actions depending on shrunk predecessors ([#453][453], [@ChickenProp][ChickenProp])
 
+## Version 1.1.2 (2022-09-02)
+
+* Support GHC 9.4 ([#461][461], [@ysangkok][ysangkok])
+* Allow newer dependencies ([#457][457], [@ysangkok][ysangkok])
+
 ## Version 1.1.1 (2022-01-29)
 
 * Support using fixed seed via `HEDGEHOG_SEED` ([#446][446], [@simfleischman][simfleischman] / [@moodmosaic][moodmosaic])
@@ -262,6 +280,30 @@
   https://github.com/jhrcek
 
 
+[parsonsmatt]:
+  https://github.com/parsonsmatt
+[shlevy]:
+  https://github.com/shlevy
+
+
+[491]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/491
+[486]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/486
+[485]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/485
+[482]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/482
+[481]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/481
+[478]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/478
+[477]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/477
+[468]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/468
+[466]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/466
 [462]:
   https://github.com/hedgehogqa/haskell-hedgehog/pull/462
 [461]:
@@ -292,6 +334,8 @@
   https://github.com/hedgehogqa/haskell-hedgehog/pull/413
 [412]:
   https://github.com/hedgehogqa/haskell-hedgehog/pull/412
+[411]:
+  https://github.com/hedgehogqa/haskell-hedgehog/pull/411
 [409]:
   https://github.com/hedgehogqa/haskell-hedgehog/pull/409
 [408]:
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,6 +3,8 @@
 doesn't seem to render the HTML portion of the markdown spec so you may
 be better off paying us a visit on GitHub instead:
 https://github.com/hedgehogqa/haskell-hedgehog
+
+https://preview.webflow.com/preview/hedgehogqa?utm_medium=preview_link&utm_source=dashboard&utm_content=hedgehogqa&preview=e42e956627c1ec686ee73fc48a20fb71&workflow=preview
 -->
 
 <div align="center">
diff --git a/hedgehog.cabal b/hedgehog.cabal
--- a/hedgehog.cabal
+++ b/hedgehog.cabal
@@ -1,4 +1,4 @@
-version: 1.2
+version: 1.3
 
 name:
   hedgehog
@@ -52,7 +52,7 @@
   build-depends:
    -- GHC 8.0.1 / base-4.9.0.0 (May 2016)
       base                            >= 4.9        && < 5
-    , ansi-terminal                   >= 0.6        && < 0.12
+    , ansi-terminal                   >= 0.6        && < 1.1
     , async                           >= 2.0        && < 2.3
     , barbies                         >= 1.0        && < 2.1
     , bytestring                      >= 0.10       && < 0.12
@@ -67,11 +67,12 @@
     , monad-control                   >= 1.0        && < 1.1
     , mtl                             >= 2.1        && < 2.4
     , pretty-show                     >= 1.6        && < 1.11
-    , primitive                       >= 0.6        && < 0.8
+    , primitive                       >= 0.6        && < 0.9
     , random                          >= 1.1        && < 1.3
-    , resourcet                       >= 1.1        && < 1.3
+    , resourcet                       >= 1.1        && < 1.4
+    , safe-exceptions                 >= 0.1        && < 0.2
     , stm                             >= 2.4        && < 2.6
-    , template-haskell                >= 2.10       && < 2.20
+    , template-haskell                >= 2.10       && < 2.21
     , text                            >= 1.1        && < 2.1
     , time                            >= 1.4        && < 1.13
     , transformers                    >= 0.5        && < 0.7
diff --git a/src/Hedgehog/Internal/Exception.hs b/src/Hedgehog/Internal/Exception.hs
--- a/src/Hedgehog/Internal/Exception.hs
+++ b/src/Hedgehog/Internal/Exception.hs
@@ -5,7 +5,7 @@
   ) where
 
 import           Control.Exception (Exception(..), AsyncException, SomeException(..), evaluate)
-import           Control.Monad.Catch (MonadCatch(..), throwM)
+import           Control.Exception.Safe (MonadCatch, catch, throwM)
 
 import           System.IO.Unsafe (unsafePerformIO)
 
diff --git a/src/Hedgehog/Internal/Gen.hs b/src/Hedgehog/Internal/Gen.hs
--- a/src/Hedgehog/Internal/Gen.hs
+++ b/src/Hedgehog/Internal/Gen.hs
@@ -175,11 +175,14 @@
   , subtermMVec
   ) where
 
-import           Control.Applicative (Alternative(..),liftA2)
+#if !MIN_VERSION_base(4,18,0)
+import           Control.Applicative (liftA2)
+#endif
+import           Control.Applicative (Alternative(..))
 import           Control.Monad (MonadPlus(..), filterM, guard, replicateM, join)
 import           Control.Monad.Base (MonadBase(..))
+import           Control.Monad.Catch (MonadThrow(throwM), MonadCatch(catch))
 import           Control.Monad.Trans.Control (MonadBaseControl(..))
-import           Control.Monad.Catch (MonadThrow(..), MonadCatch(..))
 import           Control.Monad.Error.Class (MonadError(..))
 import           Control.Monad.IO.Class (MonadIO(..))
 import           Control.Monad.Morph (MFunctor(..), MMonad(..))
@@ -1188,10 +1191,10 @@
 --
 --   /The input list must be non-empty./
 --
-element :: MonadGen m => [a] -> m a
-element = \case
+element :: (Foldable f, MonadGen m) => f a -> m a
+element fa = case toList fa of
   [] ->
-    error "Hedgehog.Gen.element: used with empty list"
+    error "Hedgehog.Gen.element: used with empty Foldable"
   xs -> do
     n <- integral $ Range.constant 0 (length xs - 1)
     pure $ xs !! n
@@ -1325,19 +1328,33 @@
 
 -- | Generates a value that satisfies a predicate.
 --
---   This is essentially:
---
--- @
---   filter p gen = 'mfilter' p gen '<|>' filter p gen
--- @
+--   Shrinks of the generated value will also satisfy the predicate. From the
+--   original generator's shrink tree, any values that fail the predicate will
+--   be removed, but any subsequent shrinks that satisfy it will be retained.
+--   Compared to 'filter', shrinking may be slower but will be optimal.
 --
---   It differs from the above in that we keep some state to avoid looping
---   forever. If we trigger these limits then the whole generator is discarded.
+--   It's possible that the predicate will never pass, or will only pass at a
+--   larger size than we're currently running at. To avoid looping forever, we
+--   limit the number of retries, and grow the size with each retry. If we retry
+--   too many times then the whole generator is discarded.
 --
 filter :: (MonadGen m, GenBase m ~ Identity) => (a -> Bool) -> m a -> m a
 filter p =
   mapMaybe (fromPred p)
 
+-- | Generates a value which is the result of the given function returning a
+--   'Just'.
+--
+--   The original generator's shrink tree will be retained, with values
+--   returning 'Nothing' removed. Subsequent shrinks of those values will be
+--   retained. Compared to 'mapMaybeT', shrinking may be slower but will be
+--   optimal.
+--
+--   It's possible that the function will never return 'Just', or will only do
+--   so a larger size than we're currently running at. To avoid looping forever,
+--   we limit the number of retries, and grow the size with each retry. If we
+--   retry too many times then the whole generator is discarded.
+--
 mapMaybe :: (MonadGen m, GenBase m ~ Identity) => (a -> Maybe b) -> m a -> m b
 mapMaybe p gen0 =
   let
@@ -1355,10 +1372,50 @@
   in
     try 0
 
+-- | Generates a value that satisfies a predicate.
+--
+--   Shrinks of the generated value will also satisfy the predicate. From the
+--   original generator's shrink tree, any values that fail the predicate will
+--   be removed, along with their subsequent shrinks. Compared to 'filter',
+--   shrinking may be faster but may also be less optimal.
+--
+--   The type is also more general, because the shrink behavior from 'filter'
+--   would force the entire shrink tree to be evaluated when applied to an
+--   impure tree.
+--
+--   This is essentially:
+--
+-- @
+--   filterT p gen = 'mfilter' p gen '<|>' filterT p gen
+-- @
+--
+--   But that could loop forever, if the predicate will never pass or will only
+--   pass at a larger size than we're currently running at. We differ from the
+--   above in keeping some state to avoid that. We limit the number of retries,
+--   and grow the size with each retry. If we retry too many times then the
+--   whole generator is discarded.
+--
 filterT :: MonadGen m => (a -> Bool) -> m a -> m a
 filterT p =
   mapMaybeT (fromPred p)
 
+-- | Generates a value which is the result of the given function returning a
+--   'Just'.
+--
+--   The original generator's shrink tree will be retained, with values
+--   returning 'Nothing' removed. Subsequent shrinks of those values will be
+--   retained. Compared to 'mapMaybeT', shrinking may be slower but will be
+--   optimal.
+--
+--   The type is also more general, because the shrink behavior from 'mapMaybe'
+--   would force the entire shrink tree to be evaluated when applied to an
+--   impure tree.
+--
+--   It's possible that the function will never return 'Just', or will only do
+--   so a larger size than we're currently running at. To avoid looping forever,
+--   we limit the number of retries, and grow the size with each retry. If we
+--   retry too many times then the whole generator is discarded.
+--
 mapMaybeT :: MonadGen m => (a -> Maybe b) -> m a -> m b
 mapMaybeT p gen0 =
   let
@@ -1744,6 +1801,20 @@
 
 -- | Generate a sample from a generator.
 --
+-- This function is useful for examining a 'Gen' in GHCi or other contexts.
+-- It is not appropriate for use in a test suite directly. You will only
+-- get a single sample from this function, and it will not give you
+-- a property test. The seed is random, so the test is not deterministic.
+--
+-- If you only want a single test to run, then use @'withTests' 1@:
+--
+-- @
+-- prop_OnlyRunOnce :: Property
+-- prop_OnlyRunOnce =
+--   'withTests' 1 $ 'property' $ do
+--     i <- Gen.int
+--     i /== 0
+-- @
 sample :: MonadIO m => Gen a -> m a
 sample gen =
   liftIO $
diff --git a/src/Hedgehog/Internal/Property.hs b/src/Hedgehog/Internal/Property.hs
--- a/src/Hedgehog/Internal/Property.hs
+++ b/src/Hedgehog/Internal/Property.hs
@@ -136,10 +136,10 @@
 
 import           Control.Applicative (Alternative(..))
 import           Control.DeepSeq (NFData, rnf)
+import           Control.Exception.Safe (MonadThrow, MonadCatch)
+import           Control.Exception.Safe (SomeException(..), displayException)
 import           Control.Monad (MonadPlus(..), (<=<))
 import           Control.Monad.Base (MonadBase(..))
-import           Control.Monad.Catch (MonadThrow(..), MonadCatch(..))
-import           Control.Monad.Catch (SomeException(..), displayException)
 import           Control.Monad.Error.Class (MonadError(..))
 import qualified Control.Monad.Fail as Fail
 import           Control.Monad.IO.Class (MonadIO(..))
diff --git a/src/Hedgehog/Internal/Region.hs b/src/Hedgehog/Internal/Region.hs
--- a/src/Hedgehog/Internal/Region.hs
+++ b/src/Hedgehog/Internal/Region.hs
@@ -14,7 +14,7 @@
 import           Control.Concurrent.STM (STM, TVar)
 import qualified Control.Concurrent.STM.TMVar as TMVar
 import qualified Control.Concurrent.STM.TVar as TVar
-import           Control.Monad.Catch (MonadMask(..), bracket)
+import           Control.Exception.Safe (MonadMask, bracket)
 import           Control.Monad.IO.Class (MonadIO(..))
 
 import           System.Console.Regions (ConsoleRegion, RegionLayout(..), LiftRegion(..))
diff --git a/src/Hedgehog/Internal/Runner.hs b/src/Hedgehog/Internal/Runner.hs
--- a/src/Hedgehog/Internal/Runner.hs
+++ b/src/Hedgehog/Internal/Runner.hs
@@ -29,7 +29,7 @@
 
 import           Control.Concurrent.STM (TVar, atomically)
 import qualified Control.Concurrent.STM.TVar as TVar
-import           Control.Monad.Catch (MonadCatch(..), catchAll)
+import           Control.Exception.Safe (MonadCatch, catchAny)
 import           Control.Monad.IO.Class (MonadIO(..))
 import           Data.Maybe (isJust)
 
@@ -226,7 +226,7 @@
           (Just t, Just s)
 
     test =
-      catchAll test0 (fail . show)
+      catchAny test0 (fail . show)
 
     terminationCriteria =
       propertyTerminationCriteria cfg
diff --git a/src/Hedgehog/Internal/Seed.hs b/src/Hedgehog/Internal/Seed.hs
--- a/src/Hedgehog/Internal/Seed.hs
+++ b/src/Hedgehog/Internal/Seed.hs
@@ -46,6 +46,7 @@
   , mix64variant13
   , mix32
   , mixGamma
+  , global
   ) where
 
 import           Control.Monad.IO.Class (MonadIO(..))
diff --git a/src/Hedgehog/Internal/State.hs b/src/Hedgehog/Internal/State.hs
--- a/src/Hedgehog/Internal/State.hs
+++ b/src/Hedgehog/Internal/State.hs
@@ -52,8 +52,8 @@
   ) where
 
 import qualified Control.Concurrent.Async.Lifted as Async
+import           Control.Exception.Safe (MonadCatch)
 import           Control.Monad (foldM, foldM_)
-import           Control.Monad.Catch (MonadCatch)
 import           Control.Monad.State.Class (MonadState, get, put, modify)
 import           Control.Monad.Morph (MFunctor(..))
 import           Control.Monad.Trans.Class (lift)
@@ -170,8 +170,8 @@
 --   type of variable because it is used in both the generation and the
 --   execution phase.
 --
---   The order of arguments makes 'Var' 'HTraverable', which is how 'Symbolic'
---   values are turned into 'Concrete' ones.
+--   The order of arguments makes 'Var' 'FunctorB' and 'TraversableB', which is
+--   how 'Symbolic' values are turned into 'Concrete' ones.
 --
 newtype Var a v =
   Var (v a)
diff --git a/src/Hedgehog/Internal/Tree.hs b/src/Hedgehog/Internal/Tree.hs
--- a/src/Hedgehog/Internal/Tree.hs
+++ b/src/Hedgehog/Internal/Tree.hs
@@ -49,11 +49,15 @@
   , renderT
   ) where
 
-import           Control.Applicative (Alternative(..), liftA2)
+#if !MIN_VERSION_base(4,18,0)
+import           Control.Applicative (liftA2)
+#endif
+import           Control.Applicative (Alternative(..))
+import           Control.Exception.Safe (Exception)
 import           Control.Monad (MonadPlus(..), guard, join)
 import           Control.Monad.Base (MonadBase(..))
+import           Control.Monad.Catch (MonadThrow(throwM), MonadCatch(catch))
 import           Control.Monad.Trans.Control ()
-import           Control.Monad.Catch (MonadThrow(..), MonadCatch(..), Exception)
 import           Control.Monad.Error.Class (MonadError(..))
 import           Control.Monad.IO.Class (MonadIO(..))
 import           Control.Monad.Morph (MFunctor(..), MMonad(..), generalize)
@@ -184,7 +188,7 @@
     pure . NodeT x $
       fmap (expand f) xs ++ unfoldForest f x
 
--- | Throw away @n@ levels of a tree's children.
+-- | Throw away all but the top @n@ levels of a tree's children.
 --
 --   /@prune 0@ will throw away all of a tree's children./
 --
