diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,33 +1,36 @@
-	# Changelog
+# Changelog
 
-	- 2.2.0 (2020-01-29)
-	* Adds the Chinese Restaurant Process (crp).
+- 2.3.0 (2020-05-02)
+  * Adds the discrete distribution (like categorical, but with supplied
+    support).
 
-	- 2.1.0 (2019-07-23)
-	* Generalises 'categorical' and 'multinomial' to take things proportional to
-	  probabilities, rather than probabilities proper.
+- 2.2.0 (2020-01-29)
+  * Adds the Chinese Restaurant Process (crp).
 
-	- 2.0.4 (2018-06-30)
-	* Clean up docs and add some additional usage information.
-	* Split the existing Student t distribution into 'student' and its
-	  generalised variant, 'gstudent'.
+- 2.1.0 (2019-07-23)
+  * Generalises 'categorical' and 'multinomial' to take things proportional to
+    probabilities, rather than probabilities proper.
 
-	- 2.0.3 (2018-05-09)
-	* Add inverse Gaussian (Wald) distribution
+- 2.0.4 (2018-06-30)
+  * Clean up docs and add some additional usage information.
+  * Split the existing Student t distribution into 'student' and its
+    generalised variant, 'gstudent'.
 
-	- 2.0.2 (2018-01-30)
-	* Add negative binomial distribution
+- 2.0.3 (2018-05-09)
+  * Add inverse Gaussian (Wald) distribution
 
-	- 2.0.1 (2018-01-30)
-	* Add Normal-Gamma and Pareto distributions
+- 2.0.2 (2018-01-30)
+  * Add negative binomial distribution
 
-	- 2.0.0 (2018-01-29)
-	* Add Laplace and Zipf-Mandelbrot distribution
-	* Rename `isoGauss` to `isoNormal` and `standard` to `standardNormal` to
-	  uniform naming scheme.
-	* Divide Haddock in sections
+- 2.0.1 (2018-01-30)
+  * Add Normal-Gamma and Pareto distributions
 
-	- 1.3.0 (2016-12-04)
-	* Generalize a couple of samplers to use Traversable rather than lists.
+- 2.0.0 (2018-01-29)
+  * Add Laplace and Zipf-Mandelbrot distribution
+  * Rename `isoGauss` to `isoNormal` and `standard` to `standardNormal` to
+    uniform naming scheme.
+  * Divide Haddock in sections
 
+- 1.3.0 (2016-12-04)
+  * Generalize a couple of samplers to use Traversable rather than lists.
 
diff --git a/mwc-probability.cabal b/mwc-probability.cabal
--- a/mwc-probability.cabal
+++ b/mwc-probability.cabal
@@ -1,5 +1,5 @@
 name:                mwc-probability
-version:             2.2.0
+version:             2.3.0
 homepage:            http://github.com/jtobin/mwc-probability
 license:             MIT
 license-file:        LICENSE
@@ -8,7 +8,8 @@
 category:            Math
 build-type:          Simple
 cabal-version:       >= 1.10
-tested-with:         GHC == 8.0.2, GHC == 8.2.2 , GHC == 8.4.2, GHC == 8.6.5
+tested-with:         GHC == 8.0.2, GHC == 8.2.2 , GHC == 8.4.2, GHC == 8.6.5,
+                     GHC == 8.8.3
 synopsis:            Sampling function-based probability distributions.
 description:
 
diff --git a/src/System/Random/MWC/Probability.hs b/src/System/Random/MWC/Probability.hs
--- a/src/System/Random/MWC/Probability.hs
+++ b/src/System/Random/MWC/Probability.hs
@@ -83,6 +83,7 @@
   , discreteUniform
   , zipf
   , categorical
+  , discrete
   , bernoulli
   , binomial
   , negativeBinomial
@@ -425,6 +426,20 @@
     [x] -> return x
     _   -> error "mwc-probability: invalid probability vector"
 {-# INLINABLE categorical #-}
+
+-- | A categorical distribution defined by the supplied support.
+--
+--   Note that the supplied probabilities should be non-negative, but are not
+--   required to sum to one.
+--
+--   >>> samples 10 (discrete [(0.1, "yeah"), (0.9, "nah")]) gen
+--   ["yeah","nah","nah","nah","nah","yeah","nah","nah","nah","nah"]
+discrete :: (Foldable f, PrimMonad m) => f (Double, a) -> Prob m a
+discrete d = do
+  let (ps, xs) = unzip (F.toList d)
+  idx <- categorical ps
+  pure (xs !! idx)
+{-# INLINABLE discrete #-}
 
 -- | The Zipf-Mandelbrot distribution.
 --
