diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # Revision history for `probability-polynomial`
 
+## 1.0.2.0 - 2026-11-05
+
+### Added
+
+* New module `Numeric.Function.Piecewise.Polynomial` containing:
+    * Function `integral` to compute the continuous antiderivative of a piecewise polynomial
+
 ## 1.0.1.0 — 2025-09-26
 
 ### Added
diff --git a/probability-polynomial.cabal b/probability-polynomial.cabal
--- a/probability-polynomial.cabal
+++ b/probability-polynomial.cabal
@@ -5,7 +5,7 @@
 -- PVP summary:  +-+------- breaking API changes
 --               | | +----- non-breaking API additions
 --               | | | +--- code changes with no API change
-version:         1.0.1.0
+version:         1.0.2.0
 synopsis:        Probability distributions via piecewise polynomials
 description:
   Package for manipulating finite probability distributions.
@@ -20,14 +20,14 @@
 homepage:        https://github.com/DeltaQ-SD/deltaq
 license:         BSD-3-Clause
 license-file:    LICENSE
-copyright:       Predictable Network Solutions Ltd., 2020-2025
+copyright:       Predictable Network Solutions Ltd., 2020-2026
 author:          Peter W. Thompson, Heinrich Apfelmus
 maintainer:      peter.thompson@pnsol.com
 extra-doc-files:
   CHANGELOG.md
   README.md
 
-tested-with:     GHC ==8.10.7 || ==9.6.7 || ==9.10.3
+tested-with:     GHC ==8.10.7 || ==9.6.7 || ==9.10.3 || ==9.12.4
 
 common warnings
   ghc-options: -Wall
@@ -44,12 +44,13 @@
   build-depends:
     , base                 >=4.14.3.0 && <5
     , containers           >=0.6      && <0.9
-    , deepseq              >=1.4.4.0  && <1.6
+    , deepseq              >=1.4.4.0  && <1.7
     , exact-combinatorics  >=0.2      && <0.3
 
   exposed-modules:
     Data.Function.Class
     Numeric.Function.Piecewise
+    Numeric.Function.Piecewise.Polynomial
     Numeric.Measure.Discrete
     Numeric.Measure.Finite.Mixed
     Numeric.Measure.Probability
@@ -67,10 +68,11 @@
     , containers
     , hspec                   >=2.11.0 && <2.12
     , probability-polynomial
-    , QuickCheck              >=2.14   && <2.17
+    , QuickCheck              >=2.14   && <2.19
 
   main-is:            Spec.hs
   other-modules:
+    Numeric.Function.Piecewise.PolynomialSpec
     Numeric.Function.PiecewiseSpec
     Numeric.Measure.DiscreteSpec
     Numeric.Measure.Finite.MixedSpec
diff --git a/src/Numeric/Function/Piecewise/Polynomial.hs b/src/Numeric/Function/Piecewise/Polynomial.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/Function/Piecewise/Polynomial.hs
@@ -0,0 +1,43 @@
+{-|
+Copyright   : Predictable Network Solutions Ltd., 2020-2026
+License     : BSD-3-Clause
+Description : Functions specific to piecewise polynomials.
+-}
+module Numeric.Function.Piecewise.Polynomial
+    ( -- * Operations
+      integral
+    ) where
+
+import Data.List
+    ( mapAccumL
+    )
+import Numeric.Function.Piecewise
+    ( Piecewise
+    , fromAscPieces
+    , toAscPieces
+    )
+import Numeric.Polynomial.Simple
+    ( Poly
+    )
+
+import qualified Numeric.Polynomial.Simple as Poly
+
+{------------------------------------------------------------------------------
+    Operations
+    Integration
+------------------------------------------------------------------------------}
+{- | The continuous antiderivative of a piecewise polynomial,
+     taking the value 0 at the start of the first piece.
+-}
+integral
+    :: (Ord a, Fractional a)
+    => Piecewise (Poly a) -> Piecewise (Poly a)
+integral = fromAscPieces . snd . mapAccumL f Poly.zero . toAscPieces
+  where
+    -- The accumulator is the antiderivative on the previous piece.
+    -- Shift the antiderivative on this piece so that it starts
+    -- where the previous one ends.
+    f before (x, p) = (q, (x, q))
+      where
+        pp = Poly.integrate p
+        q = pp + Poly.constant (Poly.eval before x - Poly.eval pp x)
diff --git a/test/Numeric/Function/Piecewise/PolynomialSpec.hs b/test/Numeric/Function/Piecewise/PolynomialSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Numeric/Function/Piecewise/PolynomialSpec.hs
@@ -0,0 +1,81 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+{-|
+Copyright   : Predictable Network Solutions Ltd., 2020-2026
+License     : BSD-3-Clause
+-}
+module Numeric.Function.Piecewise.PolynomialSpec
+    ( spec
+    , genPiecewisePoly
+    ) where
+
+import Prelude
+
+import Data.Function.Class
+    ( eval
+    )
+import Numeric.Function.Piecewise
+    ( Piecewise
+    , mapPieces
+    , toAscPieces
+    )
+import Numeric.Function.Piecewise.Polynomial
+    ( integral
+    )
+import Numeric.Function.PiecewiseSpec
+    ( genPiecewise
+    )
+import Numeric.Polynomial.Simple
+    ( Poly
+    , differentiate
+    , scale
+    )
+import Numeric.Polynomial.SimpleSpec
+    ( genPoly
+    )
+import Test.Hspec
+    ( Spec
+    , describe
+    , it
+    )
+import Test.QuickCheck
+    ( Gen
+    , (===)
+    , property
+    )
+
+{-----------------------------------------------------------------------------
+    Tests
+------------------------------------------------------------------------------}
+spec :: Spec
+spec = do
+    describe "integral" $ do
+        it "is continuous" $ property $
+            \(p :: Piecewise (Poly Rational)) ->
+                let pieces = toAscPieces (integral p)
+                    befores = 0 : map snd pieces
+                in  zipWith (\b (x, _) -> eval b x) befores pieces
+                        === map (\(x, q) -> eval q x) pieces
+
+        it "is an antiderivative" $ property $
+            \(p :: Piecewise (Poly Rational)) x ->
+                eval (mapPieces differentiate (integral p)) x
+                    === eval p x
+
+        it "is additive" $ property $
+            \p (q :: Piecewise (Poly Rational)) x ->
+                eval (integral (p + q)) x
+                    === eval (integral p + integral q) x
+
+        it "is homogeneous" $ property $
+            \(a :: Rational) (p :: Piecewise (Poly Rational)) x ->
+                eval (integral (mapPieces (scale a) p)) x
+                    === a * eval (integral p) x
+
+{-----------------------------------------------------------------------------
+    Random generators
+------------------------------------------------------------------------------}
+-- | Generate an arbitrary piecewise polynomial,
+-- with sorted breakpoints and an arbitrary polynomial on each piece.
+genPiecewisePoly :: Gen (Piecewise (Poly Rational))
+genPiecewisePoly = genPiecewise genPoly
