diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,8 @@
+1.23.1 [2025.03.03]
+-------------------
+* Add `Uniform` and `UniformRange` instances for `Plucker`, `Quaternion`, `V`,
+  and `V{0,1,2,3,4}`.
+
 1.23 [2024.04.15]
 -----------------
 * The direction of interpolation of `lerp` has been reversed;
diff --git a/linear.cabal b/linear.cabal
--- a/linear.cabal
+++ b/linear.cabal
@@ -1,6 +1,6 @@
 name:          linear
 category:      Math, Algebra
-version:       1.23
+version:       1.23.1
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
@@ -21,8 +21,11 @@
              , GHC == 8.10.7
              , GHC == 9.0.2
              , GHC == 9.2.8
-             , GHC == 9.4.5
-             , GHC == 9.6.2
+             , GHC == 9.4.8
+             , GHC == 9.6.6
+             , GHC == 9.8.4
+             , GHC == 9.10.1
+             , GHC == 9.12.1
 extra-source-files:
   .gitignore
   .hlint.yaml
@@ -55,14 +58,14 @@
     binary               >= 0.5   && < 0.9,
     bytes                >= 0.15  && < 1,
     cereal               >= 0.4.1.1 && < 0.6,
-    containers           >= 0.4   && < 0.8,
+    containers           >= 0.4   && < 0.9,
     deepseq              >= 1.1   && < 1.6,
     distributive         >= 0.5.1 && < 1,
     ghc-prim,
-    hashable             >= 1.2.7.0 && < 1.5,
+    hashable             >= 1.2.7.0 && < 1.6,
     indexed-traversable  >= 0.1.1 && < 0.2,
     lens                 >= 4.15.2 && < 6,
-    random               >= 1.0   && < 1.3,
+    random               >= 1.2   && < 1.4,
     reflection           >= 2     && < 3,
     semigroupoids        >= 5.2.1 && < 7,
     tagged               >= 0.8.6 && < 1,
@@ -124,7 +127,7 @@
   hs-source-dirs:    tests
   default-language:  Haskell2010
 
-  build-depends: base, simple-reflect >= 0.3.1
+  build-depends: base < 5, simple-reflect >= 0.3.1
 
 test-suite test
   type:           exitcode-stdio-1.0
diff --git a/src/Linear/Affine.hs b/src/Linear/Affine.hs
--- a/src/Linear/Affine.hs
+++ b/src/Linear/Affine.hs
@@ -14,10 +14,6 @@
 {-# LANGUAGE StandaloneDeriving #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
-#ifndef MIN_VERSION_hashable
-#define MIN_VERSION_hashable(x,y,z) 1
-#endif
-
 -----------------------------------------------------------------------------
 -- |
 -- License     :  BSD-style (see the file LICENSE)
diff --git a/src/Linear/Plucker.hs b/src/Linear/Plucker.hs
--- a/src/Linear/Plucker.hs
+++ b/src/Linear/Plucker.hs
@@ -9,13 +9,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveLift #-}
 
-#ifndef MIN_VERSION_vector
-#define MIN_VERSION_vector(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_transformers
-#define MIN_VERSION_transformers(x,y,z) 1
-#endif
 -----------------------------------------------------------------------------
 -- |
 -- Copyright   :  (C) 2012-2015 Edward Kmett
@@ -93,7 +86,8 @@
 import Linear.V3
 import Linear.V4
 import Linear.Vector
-import System.Random (Random(..))
+import System.Random (Random(..), Uniform)
+import System.Random.Stateful (UniformRange(..))
 
 -- | Plücker coordinates for lines in a 3-dimensional space.
 data Plucker a = Plucker !a !a !a !a !a !a deriving (Eq,Ord,Show,Read
@@ -123,6 +117,17 @@
           (d'', g4) -> case randomR (e,e') g4 of
             (e'', g5) -> case randomR (f,f') g5 of
               (f'', g6) -> (Plucker a'' b'' c'' d'' e'' f'', g6)
+
+instance Uniform a => Uniform (Plucker a) where
+
+instance UniformRange a => UniformRange (Plucker a) where
+  uniformRM (Plucker a b c d e f, Plucker a' b' c' d' e' f') g = Plucker
+    <$> uniformRM (a, a') g
+    <*> uniformRM (b, b') g
+    <*> uniformRM (c, c') g
+    <*> uniformRM (d, d') g
+    <*> uniformRM (e, e') g
+    <*> uniformRM (f, f') g
 
 instance Functor Plucker where
   fmap g (Plucker a b c d e f) = Plucker (g a) (g b) (g c) (g d) (g e) (g f)
diff --git a/src/Linear/Quaternion.hs b/src/Linear/Quaternion.hs
--- a/src/Linear/Quaternion.hs
+++ b/src/Linear/Quaternion.hs
@@ -10,18 +10,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveLift #-}
 
-#ifndef MIN_VERSION_hashable
-#define MIN_VERSION_hashable(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_vector
-#define MIN_VERSION_vector(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_base
-#define MIN_VERSION_base(x,y,z) 1
-#endif
-
 -----------------------------------------------------------------------------
 -- |
 -- Copyright   :  (C) 2012-2015 Edward Kmett
@@ -96,7 +84,8 @@
 import Linear.V4
 import Linear.Vector
 import Prelude hiding (any)
-import System.Random (Random(..))
+import System.Random (Random(..), Uniform)
+import System.Random.Stateful (UniformRange(..))
 
 -- | Quaternions
 data Quaternion a = Quaternion !a {-# UNPACK #-}!(V3 a)
@@ -119,6 +108,13 @@
   randomR (Quaternion a b, Quaternion c d) g = case randomR (a,c) g of
     (e, g') -> case randomR (b,d) g' of
       (f, g'') -> (Quaternion e f, g'')
+
+instance Uniform a => Uniform (Quaternion a) where
+
+instance UniformRange a => UniformRange (Quaternion a) where
+  uniformRM (Quaternion a b, Quaternion c d) g = Quaternion
+    <$> uniformRM (a, c) g
+    <*> uniformRM (b, d) g
 
 instance Functor Quaternion where
   fmap f (Quaternion e v) = Quaternion (f e) (fmap f v)
diff --git a/src/Linear/V.hs b/src/Linear/V.hs
--- a/src/Linear/V.hs
+++ b/src/Linear/V.hs
@@ -15,22 +15,6 @@
 {-# LANGUAGE Trustworthy #-}
 {-# LANGUAGE DeriveGeneric #-}
 
-#ifndef MIN_VERSION_hashable
-#define MIN_VERSION_hashable(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_reflection
-#define MIN_VERSION_reflection(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_transformers
-#define MIN_VERSION_transformers(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_base
-#define MIN_VERSION_base(x,y,z) 1
-#endif
-
 -----------------------------------------------------------------------------
 -- |
 -- Copyright   :  (C) 2012-2015 Edward Kmett
@@ -104,6 +88,7 @@
 import Data.Semigroup
 #endif
 import System.Random (Random(..))
+import System.Random.Stateful (Uniform(..), UniformRange(..))
 
 class Dim n where
   reflectDim :: p n -> Int
@@ -148,6 +133,15 @@
 instance (Dim n, Random a) => Random (V n a) where
   random = runState (V <$> V.replicateM (reflectDim (Proxy :: Proxy n)) (state random))
   randomR (V ls,V hs) = runState (V <$> V.zipWithM (\l h -> state $ randomR (l,h)) ls hs)
+
+instance (Dim n, Uniform a) => Uniform (V n a) where
+  uniformM g = V <$> V.replicateM (reflectDim (Proxy :: Proxy n)) (uniformM g)
+
+instance (Dim n, UniformRange a) => UniformRange (V n a) where
+  uniformRM (V ls, V hs) g = V <$> V.zipWithM (\l h -> uniformRM (l, h) g) ls hs
+#if (MIN_VERSION_random(1,3,0))
+  isInRange (V ls, V hs) (V xs) = V.and $ V.zipWith3 (\l h x -> isInRange (l, h) x) ls hs xs
+#endif
 
 data ReifiedDim (s :: Type)
 
diff --git a/src/Linear/V0.hs b/src/Linear/V0.hs
--- a/src/Linear/V0.hs
+++ b/src/Linear/V0.hs
@@ -9,22 +9,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveLift #-}
 
-#ifndef MIN_VERSION_hashable
-#define MIN_VERSION_hashable(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_vector
-#define MIN_VERSION_vector(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_transformers
-#define MIN_VERSION_transformers(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_base
-#define MIN_VERSION_base(x,y,z) 1
-#endif
-
 -----------------------------------------------------------------------------
 -- |
 -- Copyright   :  (C) 2012-2015 Edward Kmett
@@ -76,7 +60,8 @@
 import Linear.Epsilon
 import Linear.Vector
 import Linear.V
-import System.Random (Random(..))
+import System.Random (Random(..), Uniform)
+import System.Random.Stateful (UniformRange(..))
 import Prelude hiding (sum)
 
 -- $setup
@@ -110,6 +95,11 @@
   randomR _ g = (V0, g)
   randomRs _ _ = repeat V0
   randoms _ = repeat V0
+
+instance Uniform (V0 a) where
+
+instance UniformRange (V0 a) where
+  uniformRM (_, _) _ = pure V0
 
 instance Serial1 V0 where
   serializeWith _ = serialize
diff --git a/src/Linear/V1.hs b/src/Linear/V1.hs
--- a/src/Linear/V1.hs
+++ b/src/Linear/V1.hs
@@ -13,22 +13,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveLift #-}
 
-#ifndef MIN_VERSION_hashable
-#define MIN_VERSION_hashable(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_vector
-#define MIN_VERSION_vector(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_transformers
-#define MIN_VERSION_transformers(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_base
-#define MIN_VERSION_base(x,y,z) 1
-#endif
-
 -----------------------------------------------------------------------------
 -- |
 -- Copyright   :  (C) 2012-2015 Edward Kmett
@@ -79,7 +63,8 @@
 import Linear.Epsilon
 import Linear.Vector
 import Prelude hiding (sum)
-import System.Random (Random(..))
+import System.Random (Random(..), Uniform)
+import System.Random.Stateful (UniformRange(..))
 #if !(MIN_VERSION_base(4,11,0))
 import Data.Semigroup
 #endif
@@ -386,6 +371,11 @@
   randoms g = V1 <$> randoms g
   randomR (V1 a, V1 b) g = case randomR (a, b) g of (a', g') -> (V1 a', g')
   randomRs (V1 a, V1 b) g = V1 <$> randomRs (a, b) g
+
+instance Uniform a => Uniform (V1 a) where
+
+instance UniformRange a => UniformRange (V1 a) where
+  uniformRM (V1 a, V1 b) g = V1 <$> uniformRM (a, b) g
 
 instance Eq1 V1 where
   liftEq f (V1 a) (V1 b) = f a b
diff --git a/src/Linear/V2.hs b/src/Linear/V2.hs
--- a/src/Linear/V2.hs
+++ b/src/Linear/V2.hs
@@ -10,22 +10,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveLift #-}
 
-#ifndef MIN_VERSION_hashable
-#define MIN_VERSION_hashable(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_vector
-#define MIN_VERSION_vector(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_transformers
-#define MIN_VERSION_transformers(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_base
-#define MIN_VERSION_base(x,y,z) 1
-#endif
-
 -----------------------------------------------------------------------------
 -- |
 -- Copyright   :  (C) 2012-2015 Edward Kmett
@@ -88,7 +72,8 @@
 import Linear.Vector
 import Linear.V1 (R1(..),ex)
 import Prelude hiding (sum)
-import System.Random (Random(..))
+import System.Random (Random(..), Uniform)
+import System.Random.Stateful (UniformRange(..))
 
 -- $setup
 -- >>> import Control.Applicative
@@ -132,6 +117,11 @@
     (x, g') -> case randomR (b, d) g' of
       (y, g'') -> (V2 x y, g'')
   {-# inline randomR #-}
+
+instance Uniform a => Uniform (V2 a) where
+
+instance UniformRange a => UniformRange (V2 a) where
+  uniformRM (V2 a b, V2 c d) g = V2 <$> uniformRM (a, c) g <*> uniformRM (b, d) g
 
 instance Functor V2 where
   fmap f (V2 a b) = V2 (f a) (f b)
diff --git a/src/Linear/V3.hs b/src/Linear/V3.hs
--- a/src/Linear/V3.hs
+++ b/src/Linear/V3.hs
@@ -10,18 +10,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveLift #-}
 
-#ifndef MIN_VERSION_hashable
-#define MIN_VERSION_hashable(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_vector
-#define MIN_VERSION_vector(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_transformers
-#define MIN_VERSION_transformers(x,y,z) 1
-#endif
-
 -----------------------------------------------------------------------------
 -- |
 -- Copyright   :  (C) 2012-2015 Edward Kmett
@@ -87,7 +75,8 @@
 import Linear.V
 import Linear.V2
 import Linear.Vector
-import System.Random (Random(..))
+import System.Random (Random(..), Uniform)
+import System.Random.Stateful (UniformRange(..))
 
 -- $setup
 -- >>> import Control.Lens hiding (index)
@@ -130,6 +119,14 @@
     (a'', g') -> case randomR (b,b') g' of
       (b'', g'') -> case randomR (c,c') g'' of
         (c'', g''') -> (V3 a'' b'' c'', g''')
+
+instance Uniform a => Uniform (V3 a) where
+
+instance UniformRange a => UniformRange (V3 a) where
+  uniformRM (V3 a b c, V3 a' b' c') g = V3
+    <$> uniformRM (a, a') g
+    <*> uniformRM (b, b') g
+    <*> uniformRM (c, c') g
 
 instance Traversable V3 where
   traverse f (V3 a b c) = V3 <$> f a <*> f b <*> f c
diff --git a/src/Linear/V4.hs b/src/Linear/V4.hs
--- a/src/Linear/V4.hs
+++ b/src/Linear/V4.hs
@@ -10,17 +10,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveLift #-}
 
-#ifndef MIN_VERSION_hashable
-#define MIN_VERSION_hashable(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_vector
-#define MIN_VERSION_vector(x,y,z) 1
-#endif
-
-#ifndef MIN_VERSION_transformers
-#define MIN_VERSION_transformers(x,y,z) 1
-#endif
 -----------------------------------------------------------------------------
 -- |
 -- Copyright   :  (C) 2012-2015 Edward Kmett
@@ -94,7 +83,8 @@
 import Linear.V2
 import Linear.V3
 import Linear.Vector
-import System.Random (Random(..))
+import System.Random (Random(..), Uniform)
+import System.Random.Stateful (UniformRange(..))
 
 -- $setup
 -- >>> import Control.Lens hiding (index)
@@ -139,6 +129,15 @@
       (b'', g'') -> case randomR (c,c') g'' of
         (c'', g''') -> case randomR (d,d') g''' of
           (d'', g'''') -> (V4 a'' b'' c'' d'', g'''')
+
+instance Uniform a => Uniform (V4 a) where
+
+instance UniformRange a => UniformRange (V4 a) where
+  uniformRM (V4 a b c d, V4 a' b' c' d') g = V4
+    <$> uniformRM (a, a') g
+    <*> uniformRM (b, b') g
+    <*> uniformRM (c, c') g
+    <*> uniformRM (d, d') g
 
 instance Traversable V4 where
   traverse f (V4 a b c d) = V4 <$> f a <*> f b <*> f c <*> f d
