diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,151 +0,0 @@
-**v0.1.0.0**
-
-  * Initial release
-
-**v0.1.0.1**
-
-  * Improve error messages when quasi-quoters are used in a
-    non-expression context
-
-**v0.1.1.0**
-
-  * Add functions for generating Template Haskell expressions
-    to be spliced, as alternatives to using the quasi-quoters
-
-**v0.2.0.0**
-
-  * Add Template Haskell splice patterns `d10Pat` and `d10ListPat`
-  * Define `quotePat` for the quasi-quoters `d10` and `d10list`,
-    so they can now be used with pattern matching
-  * Add `Integral a` constraint to `d10` and `d10list` in the
-    `Data.D10.Num` module, because this is needed for the
-    definition of `quotePat`.
-
-**v0.2.0.1**
-
-  * Add `CHANGELOG.md` to package distribution
-
-**v0.2.1.0**
-
-  * Add functions mod-10 arithmetic functions: `(+)`, `(-)`, `(*)`
-
-**v0.2.1.2**
-
-  * Support GHC 8.8
-
-**v0.2.1.4**
-
-  * Support GHC 8.10
-
-**v0.2.1.6**
-
-  * Support `doctest-0.17`
-
-**v0.3**
-
-In module `Data.D10.Char`:
-
-  * Removed `isD10Str` (see `Data.D10.Predicate`)
-  * Type of `d10Exp` changed
-    from `Integral a => a -> Q Exp`
-    to `Integer -> Q Exp`
-  * Type of `d10Pat` changed
-    from `D10 -> Q Pat`
-    to `Integer -> Q Pat`
-  * Type of `d10ListPat` changed
-    from `[D10] -> Q Pat`
-    to `String -> Q Pat`
-
-In module `Data.D10.Num`:
-
-  * Removed `isD10Str` (see `Data.D10.Predicate`)
-  * Type of `d10Exp` changed
-    from `(Integral b, Lift a, Num a) => b -> Q Exp`
-    to `Integer -> Q Exp`
-  * Type of `d10ListExp` changed
-    from `(Lift a, Num a) => String -> Q Exp`
-    to `String -> Q Exp`
-  * Type of `d10Pat` changed
-    from `Integral a => D10 a -> Q Pat`
-    to `Integer -> Q Pat`
-  * Type of `d10ListPat` changed
-    from `Integral a => [D10 a] -> Q Pat`
-    to `String -> Q Pat`
-  * Type of `d10` changed
-    from `(Lift a, Integral a) => QuasiQuoter`
-    to `QuasiQuoter`
-  * Type of `d10list` changed
-    from `(Lift a, Integral a) => QuasiQuoter`
-    to `QuasiQuoter`
-  * Although type variables no longer appear in the
-    various Template Haskell functions, the expressions
-    and patterns they generate are polymorphic.
-
-In module `Data.D10.Safe`:
-
-  * The `D10` type now has instances of the `Data` and `Generic`.
-  * Type of `d10ListPat` changed
-    from `[D10] -> Q Pat`
-    to `String -> Q Pat`
-  * Removed `d10Exp`, `d10Pat`, and `d10`
-
-Other changes:
-
-  * `doctest` test dependency has been removed, and
-    `hedgehog` dependency has been added instead
-
-**v0.3.0.1**
-
-  * Support GHC 9.0, base 4.15, template-haskell 2.17
-
-**v1**
-
-Removed the `Data` prefix from module names.
-
-  * `Data.D10.Char` is now `D10.Char`
-  * `Data.D10.Num` is now `D10.Num`
-  * `Data.D10.Predicate` is now `D10.Predicate`
-  * `Data.D10.Safe` is now `D10.Safe`
-
-Constructors for `D10` are no longer exported by the modules formerly
-known as `Data.D10.Char` and `Data.D10.Num`. They have moved to the
-new modules `D10.Char.Unsafe` and `D10.Num.Unsafe` respectively.
-
-Operators `(+)`, `(-)`, and `(*)` have been moved into their own
-separate modules, as the names conflict with `Prelude` functions.
-These new modules are:
-
-  * `D10.Char.Arithmetic`
-  * `D10.Num.Arithmetic`
-  * `D10.Safe.Arithmetic`
-
-Other new modules:
-
-  * `D10.Char.Conversions`
-  * `D10.Char.Quotes`
-  * `D10.Char.Splices`
-  * `D10.Char.Type`
-  * `D10.Num.Conversions`
-  * `D10.Num.Quotes`
-  * `D10.Num.Splices`
-  * `D10.Num.Type`
-  * `D10.Safe.Conversions`
-  * `D10.Safe.Quotes`
-  * `D10.Safe.Splices`
-  * `D10.Safe.Type`
-
-All instances of the `Language.Haskell.TH.Syntax.Lift` class
-have been removed
-
-Added *Safe Haskell* language flags (`Safe`, `Trustworthy`, `Unsafe`)
-to indicate which modules permit constructing invalid values
-
-Required Cabal version required is raised from 2.2 to 3.0
-
-**v1.0.0.1**
-
-Remove `README.md` from the Cabal package
-
-**v1.0.0.2**
-
-Support GHC 9.2
diff --git a/d10.cabal b/d10.cabal
--- a/d10.cabal
+++ b/d10.cabal
@@ -1,7 +1,7 @@
 cabal-version: 3.0
 
 name: d10
-version: 1.0.0.2
+version: 1.0.1.0
 category: Data
 synopsis: Digits 0-9
 
@@ -66,9 +66,6 @@
 
 build-type: Simple
 
-extra-source-files:
-    CHANGELOG.md
-
 source-repository head
     type: git
     location: https://github.com/typeclasses/d10
@@ -77,28 +74,37 @@
     default-language: Haskell2010
     ghc-options: -Wall
     default-extensions:
-        DeriveDataTypeable DeriveGeneric DeriveLift
-        DerivingStrategies InstanceSigs QuasiQuotes
-        ScopedTypeVariables TypeApplications
+        DeriveAnyClass DeriveDataTypeable DeriveGeneric
+        DeriveLift DerivingStrategies InstanceSigs
+        QuasiQuotes ScopedTypeVariables TypeApplications
 
 common library-dependencies
     build-depends:
-        base ^>= 4.10 || ^>= 4.11 || ^>= 4.12
-          || ^>= 4.13 || ^>= 4.14 || ^>= 4.15
+        base ^>= 4.13 || ^>= 4.14 || ^>= 4.15
           || ^>= 4.16
+      , hashable ^>= 1.3 || ^>= 1.4
       , template-haskell
-             ^>= 2.12 || ^>= 2.13 || ^>= 2.14
-          || ^>= 2.15 || ^>= 2.16 || ^>= 2.17
+             ^>= 2.15 || ^>= 2.16 || ^>= 2.17
           || ^>= 2.18
 
-common test
+common test-language
     import: language
+    default-extensions:
+        GeneralizedNewtypeDeriving
+        TemplateHaskell
+
+common test-dependencies
     import: library-dependencies
+    build-depends:
+        d10
+      , hedgehog ^>= 1.0.1 || ^>= 1.1
+
+common test
+    import: test-language
+    import: test-dependencies
     hs-source-dirs: test
-    other-modules: AssertQFails Fallible
-    build-depends: d10, hedgehog ^>= 1.0
-    default-extensions: GeneralizedNewtypeDeriving
-                        TemplateHaskell
+    build-depends:
+        d10-test
 
 library
     import: language
@@ -126,6 +132,14 @@
           , D10.Safe.Splices
           , D10.Safe.Type
       , D10.Predicate
+
+library d10-test
+    import: test-language
+    import: test-dependencies
+    hs-source-dirs: library/d10-test
+    exposed-modules:
+        AssertQFails
+      , Fallible
 
 test-suite char
     import: test
diff --git a/library/d10-test/AssertQFails.hs b/library/d10-test/AssertQFails.hs
new file mode 100644
--- /dev/null
+++ b/library/d10-test/AssertQFails.hs
@@ -0,0 +1,15 @@
+module AssertQFails where
+
+import Hedgehog
+
+import Control.Exception (try, SomeException)
+import Control.Monad.IO.Class (liftIO)
+import Language.Haskell.TH (runQ, Q)
+
+qFails :: Show a => Q a -> PropertyT IO ()
+qFails (q :: Q a) =
+  do
+    result <- liftIO (try (runQ q) :: IO (Either SomeException a))
+    case result of
+        Left _ -> success
+        Right _ -> failure
diff --git a/library/d10-test/Fallible.hs b/library/d10-test/Fallible.hs
new file mode 100644
--- /dev/null
+++ b/library/d10-test/Fallible.hs
@@ -0,0 +1,10 @@
+module Fallible where
+
+import Control.Monad.Fail (MonadFail (fail))
+import Prelude hiding (fail)
+
+newtype Fallible a = Fallible (Either String a)
+    deriving newtype (Functor, Applicative, Monad, Eq, Show)
+
+instance MonadFail Fallible where
+    fail = Fallible . Left
diff --git a/src/D10/Char/Unsafe.hs b/src/D10/Char/Unsafe.hs
--- a/src/D10/Char/Unsafe.hs
+++ b/src/D10/Char/Unsafe.hs
@@ -5,6 +5,7 @@
 import qualified D10.Predicate as Predicate
 
 import Data.Char (chr, ord)
+import Data.Hashable (Hashable)
 import Data.Monoid (Endo (..))
 
 ---------------------------------------------------
@@ -16,6 +17,7 @@
       --   that you should generally avoid using it directly, because it
       --   allows constructing invalid 'D10' values.
     deriving (Eq, Ord)
+    deriving newtype Hashable
 
 ---------------------------------------------------
 
diff --git a/src/D10/Num/Unsafe.hs b/src/D10/Num/Unsafe.hs
--- a/src/D10/Num/Unsafe.hs
+++ b/src/D10/Num/Unsafe.hs
@@ -5,6 +5,7 @@
 import qualified D10.Predicate as Predicate
 
 import Data.Char (chr, ord)
+import Data.Hashable (Hashable)
 import Data.Monoid (Endo (..))
 
 ---------------------------------------------------
@@ -16,7 +17,8 @@
       -- ^ The constructor's name include the word "unsafe" as a reminder
       --   that you should generally avoid using it directly, because it
       --   allows constructing invalid 'D10' values.
-    deriving (Eq, Ord)
+    deriving stock (Eq, Ord)
+    deriving newtype Hashable
 
 ---------------------------------------------------
 
diff --git a/src/D10/Safe.hs b/src/D10/Safe.hs
--- a/src/D10/Safe.hs
+++ b/src/D10/Safe.hs
@@ -82,11 +82,11 @@
 
 {- $bounded
 
--- >>> minBound :: D10
--- D0
---
--- >>> maxBound :: D10
--- D9
+>>> minBound :: D10
+D0
+
+>>> maxBound :: D10
+D9
 
 -}
 
diff --git a/src/D10/Safe/Type.hs b/src/D10/Safe/Type.hs
--- a/src/D10/Safe/Type.hs
+++ b/src/D10/Safe/Type.hs
@@ -3,6 +3,7 @@
 module D10.Safe.Type (D10 (..)) where
 
 import Data.Data (Data)
+import Data.Hashable (Hashable)
 import GHC.Generics (Generic)
 
 -- | A whole number between /0/ and /9/
@@ -17,4 +18,5 @@
     | D7  -- ^ Seven
     | D8  -- ^ Eight
     | D9  -- ^ Nine
-    deriving (Bounded, Enum, Eq, Ord, Show, Data, Generic)
+    deriving stock (Bounded, Enum, Eq, Ord, Show, Data, Generic)
+    deriving anyclass Hashable
diff --git a/test/AssertQFails.hs b/test/AssertQFails.hs
deleted file mode 100644
--- a/test/AssertQFails.hs
+++ /dev/null
@@ -1,15 +0,0 @@
-module AssertQFails where
-
-import Hedgehog
-
-import Control.Exception (try, SomeException)
-import Control.Monad.IO.Class (liftIO)
-import Language.Haskell.TH (runQ, Q)
-
-qFails :: Show a => Q a -> PropertyT IO ()
-qFails (q :: Q a) =
-  do
-    result <- liftIO (try (runQ q) :: IO (Either SomeException a))
-    case result of
-        Left _ -> success
-        Right _ -> failure
diff --git a/test/Fallible.hs b/test/Fallible.hs
deleted file mode 100644
--- a/test/Fallible.hs
+++ /dev/null
@@ -1,10 +0,0 @@
-module Fallible where
-
-import Control.Monad.Fail (MonadFail (fail))
-import Prelude hiding (fail)
-
-newtype Fallible a = Fallible (Either String a)
-    deriving newtype (Functor, Applicative, Monad, Eq, Show)
-
-instance MonadFail Fallible where
-    fail = Fallible . Left
diff --git a/test/char.hs b/test/char.hs
--- a/test/char.hs
+++ b/test/char.hs
@@ -240,6 +240,8 @@
 
 prop_arithmetic_examples :: Property
 prop_arithmetic_examples = withTests 1 $ property $ do
+    [d10|0|] + [d10|3|] === [d10|3|]
+    [d10|3|] + [d10|6|] === [d10|9|]
     [d10|2|] + [d10|3|] === [d10|5|]
     [d10|6|] + [d10|7|] === [d10|3|]
     [d10|7|] - [d10|5|] === [d10|2|]
diff --git a/test/num.hs b/test/num.hs
--- a/test/num.hs
+++ b/test/num.hs
@@ -243,6 +243,8 @@
 
 prop_arithmetic_examples :: Property
 prop_arithmetic_examples = withTests 1 $ property $ do
+    [d10|0|] + [d10|3|] === ([d10|3|] :: D10 Int32)
+    [d10|3|] + [d10|6|] === ([d10|9|] :: D10 Int32)
     [d10|2|] + [d10|3|] === ([d10|5|] :: D10 Int32)
     [d10|6|] + [d10|7|] === ([d10|3|] :: D10 Int32)
     [d10|7|] - [d10|5|] === ([d10|2|] :: D10 Int32)
diff --git a/test/safe.hs b/test/safe.hs
--- a/test/safe.hs
+++ b/test/safe.hs
@@ -272,6 +272,8 @@
 
 prop_arithmetic_examples :: Property
 prop_arithmetic_examples = withTests 1 $ property $ do
+    D0 + D3 === D3
+    D3 + D6 === D9
     D2 + D3 === D5
     D6 + D7 === D3
     D7 - D5 === D2
