diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,24 @@
+0.6
+
+* Removed the `Digit` datatype
+* Added new datatypes with appropriate `D*` instances
+  * `BinDigit`
+  * `OctDigit`
+  * `DecDigit`
+  * `HexDigit`
+  * `HeXDigit`
+  * `HEXDigit`
+* Culled most of the doctests, and leaving one or two per function to illustrate
+  usage
+* Juggled re-exports to make the library easier to use and to improve documentation
+* Added `Data.Digit.Enum`, which contains ascending-order enumerations of the new datatypes
+* Added integral conversion functions for the new datatypes
+
+0.5.3
+
+* Bump version of [tasty-hedgehog, hedgehog, papa]
+* Updated default.nix
+
 0.5.2
 
 * Add `Data.Digit.Natural (_NaturalDigits, naturalToDigits, digitsToNatural)`
diff --git a/digit.cabal b/digit.cabal
--- a/digit.cabal
+++ b/digit.cabal
@@ -1,5 +1,5 @@
 name:               digit
-version:            0.5.2
+version:            0.6
 license:            BSD3
 license-file:       LICENCE
 author:             Queensland Functional Programming Lab <oᴉ˙ldɟb@llǝʞsɐɥ>
@@ -13,6 +13,7 @@
 cabal-version:      >= 1.10
 build-type:         Simple
 extra-source-files: CONTRIBUTORS, changelog.md
+tested-with:        GHC == 8.4.1, GHC == 8.2.2, GHC == 8.0.2, GHC == 7.10.3
 description:
   <<http://i.imgur.com/uZnp9ke.png>>
   .
@@ -32,7 +33,7 @@
                     , parsers          >= 0.12.3 && < 0.13
                     , semigroups       >= 0.12 && < 1.0
                     , template-haskell >= 2.8 && < 3
-                    , papa             >= 0.3 && < 0.4
+                    , papa             >= 0.3.1 && < 0.4
                     , semigroupoids    >= 5 && < 6
                     , scientific       >= 0.3 && < 0.4
 
@@ -82,8 +83,8 @@
                     Data.Digit.DDd
                     Data.Digit.DEe
                     Data.Digit.DFf
-                    Data.Digit.Digit
                     Data.Digit.Char
+                    Data.Digit.Enum
                     Data.Digit.Integral
 
 
@@ -98,13 +99,13 @@
                     Haskell2010
 
   build-depends:
-                    base             >=4.9    && <4.12
+                    base             >=4.8    && <4.12
                     , lens           >=4.0    && <5
                     , ansi-wl-pprint >=0.6    && <0.7
-                    , hedgehog       >=0.5    && <0.6
-                    , tasty          >=0.11   && <1.1
+                    , hedgehog       >=0.5    && <0.7
+                    , tasty          >=0.11   && <1.2
                     , tasty-hspec    >=1.1    && <1.2
-                    , papa           >=0.3    && <0.4
+                    , papa           >= 0.3.1 && < 0.4
                     , parsec         >=3.1    && <3.2
                     , parsers        >=0.12.3 && <0.13
                     , pretty         >=1.1    && <1.2
diff --git a/src/Data/Digit.hs b/src/Data/Digit.hs
--- a/src/Data/Digit.hs
+++ b/src/Data/Digit.hs
@@ -1,44 +1,26 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 
 module Data.Digit (
-  module D
+  module Data.Digit.Binary
+, module Data.Digit.Decimal
+, module Data.Digit.Octal
+, module Data.Digit.Hexadecimal
+, module Data.Digit.HeXaDeCiMaL
+, module Data.Digit.HEXADECIMAL
+-- * Utilities
+, module Data.Digit.Char
+, module Data.Digit.Enum
+, module Data.Digit.Integral
+, module Data.Digit.Natural
 ) where
 
-import Data.Digit.Binary as D
-import Data.Digit.Decimal as D
-import Data.Digit.Natural as D
-import Data.Digit.Octal as D
-import Data.Digit.Hexadecimal as D
-import Data.Digit.HeXaDeCiMaL as D
-import Data.Digit.HEXADECIMAL as D
-import Data.Digit.D0 as D
-import Data.Digit.D1 as D
-import Data.Digit.D2 as D
-import Data.Digit.D3 as D
-import Data.Digit.D4 as D
-import Data.Digit.D5 as D
-import Data.Digit.D6 as D
-import Data.Digit.D7 as D
-import Data.Digit.D8 as D
-import Data.Digit.D9 as D
-import Data.Digit.Da as D
-import Data.Digit.DA as D
-import Data.Digit.Db as D
-import Data.Digit.DB as D
-import Data.Digit.Dc as D
-import Data.Digit.DC as D
-import Data.Digit.Dd as D
-import Data.Digit.DD as D
-import Data.Digit.De as D
-import Data.Digit.DE as D
-import Data.Digit.Df as D
-import Data.Digit.DF as D
-import Data.Digit.DAa as D
-import Data.Digit.DBb as D
-import Data.Digit.DCc as D
-import Data.Digit.DDd as D
-import Data.Digit.DEe as D
-import Data.Digit.DFf as D
-import Data.Digit.Digit as D
-import Data.Digit.Integral as D
-import Data.Digit.Char as D
+import Data.Digit.Binary
+import Data.Digit.Decimal
+import Data.Digit.Octal
+import Data.Digit.Hexadecimal
+import Data.Digit.HeXaDeCiMaL
+import Data.Digit.HEXADECIMAL
+import Data.Digit.Char
+import Data.Digit.Enum
+import Data.Digit.Integral
+import Data.Digit.Natural
diff --git a/src/Data/Digit/Binary.hs b/src/Data/Digit/Binary.hs
--- a/src/Data/Digit/Binary.hs
+++ b/src/Data/Digit/Binary.hs
@@ -1,39 +1,41 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 module Data.Digit.Binary(
-  BinaryNoZero
+  BinDigit(..)
+, BinaryNoZero
 , Binary
 , parseBinaryNoZero
 , parseBinary
+-- * Prisms
+, _BinDigit0
+, _BinDigit1
+-- * Re-exports
+, module Data.Digit.D0
+, module Data.Digit.D1
 ) where
 
+import Prelude (Eq, Show, Ord)
+import Control.Lens.TH (makePrisms)
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.D0(D0, parse0)
-import Data.Digit.D1(D1, parse1)
+import Data.Digit.D0
+import Data.Digit.D1
 
--- $setup
--- >>> import Text.Parsec(parse, ParseError, eof)
--- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
--- >>> import Papa
+data BinDigit
+  = BinDigit0
+  | BinDigit1
+  deriving (Show, Eq, Ord)
 
+makePrisms ''BinDigit
+
+instance D0 BinDigit where; d0 = _BinDigit0
+instance D1 BinDigit where; d1 = _BinDigit1
+
 type BinaryNoZero d =
   D1 d
 
--- |
---
--- >>> parse (parseBinaryNoZero <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseBinaryNoZero "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> isn't _Right (parse parseBinaryNoZero "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "1") ==> isn't _Right (parse parseBinaryNoZero "test" [c] :: Either ParseError Digit)
 parseBinaryNoZero ::
   (BinaryNoZero d, CharParsing p) =>
   p d
@@ -43,24 +45,6 @@
 type Binary d =
   (D0 d, BinaryNoZero d)
 
--- |
---
--- >>> parse (parseBinary <* eof) "test" "0" :: Either ParseError Digit
--- Right 0
---
--- >>> parse parseBinary "test" "0xyz" :: Either ParseError Digit
--- Right 0
---
--- >>> parse (parseBinary <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseBinary "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> isn't _Right (parse parseBinary "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "01") ==> isn't _Right (parse parseBinary "test" [c] :: Either ParseError Digit)
 parseBinary ::
   (Binary d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/Char.hs b/src/Data/Digit/Char.hs
--- a/src/Data/Digit/Char.hs
+++ b/src/Data/Digit/Char.hs
@@ -1,16 +1,22 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 
 module Data.Digit.Char(
+-- * Binary
   charBinaryNoZero
 , charBinary
+-- * Octal
 , charOctalNoZero
 , charOctal
+-- * Decimal
 , charDecimalNoZero
 , charDecimal
+-- * Hexadecimal
 , charHexadecimalNoZero
 , charHexadecimal
+-- * HEXADECIMAL
 , charHEXADECIMALNoZero
 , charHEXADECIMAL
+-- * HeXaDeCiMaL
 , charHeXaDeCiMaLNoZero
 , charHeXaDeCiMaL
 ) where
@@ -22,43 +28,19 @@
 import Data.Digit.Hexadecimal as D
 import Data.Digit.HeXaDeCiMaL as D
 import Data.Digit.HEXADECIMAL as D
-import Data.Digit.D0 as D
-import Data.Digit.D1 as D
-import Data.Digit.D2 as D
-import Data.Digit.D3 as D
-import Data.Digit.D4 as D
-import Data.Digit.D5 as D
-import Data.Digit.D6 as D
-import Data.Digit.D7 as D
-import Data.Digit.D8 as D
-import Data.Digit.D9 as D
-import Data.Digit.Da as D
-import Data.Digit.DA as D
-import Data.Digit.Db as D
-import Data.Digit.DB as D
-import Data.Digit.Dc as D
-import Data.Digit.DC as D
-import Data.Digit.Dd as D
-import Data.Digit.DD as D
-import Data.Digit.De as D
-import Data.Digit.DE as D
-import Data.Digit.Df as D
-import Data.Digit.DF as D
 import Papa
 
 
 -- $setup
--- >>> import Data.Digit.Digit
+-- >>> import Data.Digit
 
 -- |
 --
--- >>> '1' ^? charBinaryNoZero :: Maybe Digit
--- Just 1
+-- >>> '1' ^? charBinaryNoZero :: Maybe BinDigit
+-- Just BinDigit1
 --
--- >>> charBinaryNoZero # Digit1
+-- >>> charBinaryNoZero # BinDigit1
 -- '1'
---
--- prop> \c -> c /= '1' ==> (c ^? charBinaryNoZero == Nothing)
 charBinaryNoZero ::
   BinaryNoZero d =>
   Prism'
@@ -69,19 +51,11 @@
   
 -- |
 --
--- >>> '0' ^? charBinary :: Maybe Digit
--- Just 0
---
--- >>> '1' ^? charBinary :: Maybe Digit
--- Just 1
+-- >>> '0' ^? charBinary :: Maybe BinDigit
+-- Just BinDigit0
 --
--- >>> charBinary # Digit0 :: Char
+-- >>> charBinary # BinDigit0 :: Char
 -- '0'
---
--- >>> charBinary # Digit1 :: Char
--- '1'
---
--- prop> \c -> (c `notElem` "01") ==> (c ^? charBinary == Nothing)
 charBinary ::
   Binary d =>
   Prism'
@@ -92,49 +66,11 @@
   
 -- |
 --
--- >>> '1' ^? charOctalNoZero :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charOctalNoZero :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charOctalNoZero :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charOctalNoZero :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charOctalNoZero :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charOctalNoZero :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charOctalNoZero :: Maybe Digit
--- Just 7
---
--- >>> charOctalNoZero # Digit1 :: Char
--- '1'
---
--- >>> charOctalNoZero # Digit2 :: Char
--- '2'
---
--- >>> charOctalNoZero # Digit3 :: Char
--- '3'
---
--- >>> charOctalNoZero # Digit4 :: Char
--- '4'
+-- >>> '6' ^? charOctalNoZero :: Maybe OctDigit
+-- Just OctDigit6
 --
--- >>> charOctalNoZero # Digit5 :: Char
+-- >>> charOctalNoZero # OctDigit5 :: Char
 -- '5'
---
--- >>> charOctalNoZero # Digit6 :: Char
--- '6'
---
--- >>> charOctalNoZero # Digit7 :: Char
--- '7'
---
--- prop> \c -> (c `notElem` "1234567") ==> (c ^? charOctalNoZero == Nothing)
 charOctalNoZero ::
   OctalNoZero d =>
   Prism'
@@ -144,56 +80,11 @@
   associatePrism ('1', d1) [('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7)]
   
 -- |
---
--- >>> '0' ^? charOctal :: Maybe Digit
--- Just 0
---
--- >>> '1' ^? charOctal :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charOctal :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charOctal :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charOctal :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charOctal :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charOctal :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charOctal :: Maybe Digit
--- Just 7
---
--- >>> charOctal # Digit0 :: Char
--- '0'
---
--- >>> charOctal # Digit1 :: Char
--- '1'
---
--- >>> charOctal # Digit2 :: Char
--- '2'
---
--- >>> charOctal # Digit3 :: Char
--- '3'
---
--- >>> charOctal # Digit4 :: Char
--- '4'
---
--- >>> charOctal # Digit5 :: Char
--- '5'
---
--- >>> charOctal # Digit6 :: Char
--- '6'
+-- >>> '7' ^? charOctal :: Maybe OctDigit
+-- Just OctDigit7
 --
--- >>> charOctal # Digit7 :: Char
+-- >>> charOctal # OctDigit7 :: Char
 -- '7'
---
--- prop> \c -> (c `notElem` "01234567") ==> (c ^? charOctal == Nothing)
 charOctal ::
   Octal d =>
   Prism'
@@ -203,62 +94,11 @@
   associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7)]
   
 -- |
---
--- >>> '1' ^? charDecimalNoZero :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charDecimalNoZero :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charDecimalNoZero :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charDecimalNoZero :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charDecimalNoZero :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charDecimalNoZero :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charDecimalNoZero :: Maybe Digit
--- Just 7
---
--- >>> '8' ^? charDecimalNoZero :: Maybe Digit
--- Just 8
---
--- >>> '9' ^? charDecimalNoZero :: Maybe Digit
--- Just 9
---
--- >>> charDecimalNoZero # Digit1 :: Char
--- '1'
---
--- >>> charDecimalNoZero # Digit2 :: Char
--- '2'
---
--- >>> charDecimalNoZero # Digit3 :: Char
--- '3'
---
--- >>> charDecimalNoZero # Digit4 :: Char
--- '4'
---
--- >>> charDecimalNoZero # Digit5 :: Char
--- '5'
---
--- >>> charDecimalNoZero # Digit6 :: Char
--- '6'
---
--- >>> charDecimalNoZero # Digit7 :: Char
--- '7'
---
--- >>> charDecimalNoZero # Digit8 :: Char
--- '8'
+-- >>> '9' ^? charDecimalNoZero :: Maybe DecDigit
+-- Just DecDigit9
 --
--- >>> charDecimalNoZero # Digit9 :: Char
+-- >>> charDecimalNoZero # DecDigit9 :: Char
 -- '9'
---
--- prop> \c -> (c `notElem` "123456789") ==> (c ^? charDecimalNoZero == Nothing)
 charDecimalNoZero ::
   DecimalNoZero d =>
   Prism'
@@ -268,68 +108,11 @@
   associatePrism ('1', d1) [('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9)]
   
 -- |
---
--- >>> '0' ^? charDecimal :: Maybe Digit
--- Just 0
---
--- >>> '1' ^? charDecimal :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charDecimal :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charDecimal :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charDecimal :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charDecimal :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charDecimal :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charDecimal :: Maybe Digit
--- Just 7
---
--- >>> '8' ^? charDecimal :: Maybe Digit
--- Just 8
---
--- >>> '9' ^? charDecimal :: Maybe Digit
--- Just 9
---
--- >>> charDecimal # Digit0 :: Char
--- '0'
---
--- >>> charDecimal # Digit1 :: Char
--- '1'
---
--- >>> charDecimal # Digit2 :: Char
--- '2'
---
--- >>> charDecimal # Digit3 :: Char
--- '3'
---
--- >>> charDecimal # Digit4 :: Char
--- '4'
---
--- >>> charDecimal # Digit5 :: Char
--- '5'
---
--- >>> charDecimal # Digit6 :: Char
--- '6'
---
--- >>> charDecimal # Digit7 :: Char
--- '7'
---
--- >>> charDecimal # Digit8 :: Char
--- '8'
+-- >>> '9' ^? charDecimal :: Maybe DecDigit
+-- Just DecDigit9
 --
--- >>> charDecimal # Digit9 :: Char
+-- >>> charDecimal # DecDigit9 :: Char
 -- '9'
---
--- prop> \c -> (c `notElem` "0123456789") ==> (c ^? charDecimal == Nothing)
 charDecimal ::
   Decimal d =>
   Prism'
@@ -339,98 +122,11 @@
   associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9)]
   
 -- |
---
--- >>> '1' ^? charHexadecimalNoZero :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charHexadecimalNoZero :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charHexadecimalNoZero :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charHexadecimalNoZero :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charHexadecimalNoZero :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charHexadecimalNoZero :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charHexadecimalNoZero :: Maybe Digit
--- Just 7
---
--- >>> '8' ^? charHexadecimalNoZero :: Maybe Digit
--- Just 8
---
--- >>> '9' ^? charHexadecimalNoZero :: Maybe Digit
--- Just 9
---
--- >>> 'a' ^? charHexadecimalNoZero :: Maybe Digit
--- Just a
---
--- >>> 'b' ^? charHexadecimalNoZero :: Maybe Digit
--- Just b
---
--- >>> 'c' ^? charHexadecimalNoZero :: Maybe Digit
--- Just c
---
--- >>> 'd' ^? charHexadecimalNoZero :: Maybe Digit
--- Just d
---
--- >>> 'e' ^? charHexadecimalNoZero :: Maybe Digit
--- Just e
---
--- >>> 'f' ^? charHexadecimalNoZero :: Maybe Digit
--- Just f
---
--- >>> charHexadecimalNoZero # Digit1 :: Char
--- '1'
---
--- >>> charHexadecimalNoZero # Digit2 :: Char
--- '2'
---
--- >>> charHexadecimalNoZero # Digit3 :: Char
--- '3'
---
--- >>> charHexadecimalNoZero # Digit4 :: Char
--- '4'
---
--- >>> charHexadecimalNoZero # Digit5 :: Char
--- '5'
---
--- >>> charHexadecimalNoZero # Digit6 :: Char
--- '6'
---
--- >>> charHexadecimalNoZero # Digit7 :: Char
--- '7'
---
--- >>> charHexadecimalNoZero # Digit8 :: Char
--- '8'
---
--- >>> charHexadecimalNoZero # Digit9 :: Char
--- '9'
---
--- >>> charHexadecimalNoZero # Digita :: Char
--- 'a'
---
--- >>> charHexadecimalNoZero # Digitb :: Char
--- 'b'
---
--- >>> charHexadecimalNoZero # Digitc :: Char
--- 'c'
---
--- >>> charHexadecimalNoZero # Digitd :: Char
--- 'd'
---
--- >>> charHexadecimalNoZero # Digite :: Char
--- 'e'
+-- >>> 'f' ^? charHexadecimalNoZero :: Maybe HexDigit
+-- Just HexDigitf
 --
--- >>> charHexadecimalNoZero # Digitf :: Char
+-- >>> charHexadecimalNoZero # HexDigitf :: Char
 -- 'f'
---
--- prop> \c -> (c `notElem` "123456789abcdef") ==> (c ^? charHexadecimalNoZero == Nothing)
 charHexadecimalNoZero ::
   HexadecimalNoZero d =>
   Prism'
@@ -440,104 +136,11 @@
   associatePrism ('1', d1) [('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('a', da), ('b', db), ('c', dc), ('d', dd), ('e', de), ('f', df)]
   
 -- |
---
--- >>> '0' ^? charHexadecimal :: Maybe Digit
--- Just 0
---
--- >>> '1' ^? charHexadecimal :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charHexadecimal :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charHexadecimal :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charHexadecimal :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charHexadecimal :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charHexadecimal :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charHexadecimal :: Maybe Digit
--- Just 7
---
--- >>> '8' ^? charHexadecimal :: Maybe Digit
--- Just 8
---
--- >>> '9' ^? charHexadecimal :: Maybe Digit
--- Just 9
---
--- >>> 'a' ^? charHexadecimal :: Maybe Digit
--- Just a
---
--- >>> 'b' ^? charHexadecimal :: Maybe Digit
--- Just b
---
--- >>> 'c' ^? charHexadecimal :: Maybe Digit
--- Just c
---
--- >>> 'd' ^? charHexadecimal :: Maybe Digit
--- Just d
---
--- >>> 'e' ^? charHexadecimal :: Maybe Digit
--- Just e
---
--- >>> 'f' ^? charHexadecimal :: Maybe Digit
--- Just f
---
--- >>> charHexadecimal # Digit0 :: Char
--- '0'
---
--- >>> charHexadecimal # Digit1 :: Char
--- '1'
---
--- >>> charHexadecimal # Digit2 :: Char
--- '2'
---
--- >>> charHexadecimal # Digit3 :: Char
--- '3'
---
--- >>> charHexadecimal # Digit4 :: Char
--- '4'
---
--- >>> charHexadecimal # Digit5 :: Char
--- '5'
---
--- >>> charHexadecimal # Digit6 :: Char
--- '6'
---
--- >>> charHexadecimal # Digit7 :: Char
--- '7'
---
--- >>> charHexadecimal # Digit8 :: Char
--- '8'
---
--- >>> charHexadecimal # Digit9 :: Char
--- '9'
---
--- >>> charHexadecimal # Digita :: Char
--- 'a'
---
--- >>> charHexadecimal # Digitb :: Char
--- 'b'
---
--- >>> charHexadecimal # Digitc :: Char
--- 'c'
---
--- >>> charHexadecimal # Digitd :: Char
--- 'd'
---
--- >>> charHexadecimal # Digite :: Char
--- 'e'
+-- >>> 'f' ^? charHexadecimal :: Maybe HexDigit
+-- Just HexDigitf
 --
--- >>> charHexadecimal # Digitf :: Char
+-- >>> charHexadecimal # HexDigitf :: Char
 -- 'f'
---
--- prop> \c -> (c `notElem` "0123456789abcdef") ==> (c ^? charHexadecimal == Nothing)
 charHexadecimal ::
   Hexadecimal d =>
   Prism'
@@ -547,98 +150,11 @@
   associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('a', da), ('b', db), ('c', dc), ('d', dd), ('e', de), ('f', df)]
   
 -- |
---
--- >>> '1' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just 7
---
--- >>> '8' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just 8
---
--- >>> '9' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just 9
---
--- >>> 'A' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just A
---
--- >>> 'B' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just B
---
--- >>> 'C' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just C
---
--- >>> 'D' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just D
---
--- >>> 'E' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just E
---
--- >>> 'F' ^? charHEXADECIMALNoZero :: Maybe Digit
--- Just F
---
--- >>> charHEXADECIMALNoZero # Digit1 :: Char
--- '1'
---
--- >>> charHEXADECIMALNoZero # Digit2 :: Char
--- '2'
---
--- >>> charHEXADECIMALNoZero # Digit3 :: Char
--- '3'
---
--- >>> charHEXADECIMALNoZero # Digit4 :: Char
--- '4'
---
--- >>> charHEXADECIMALNoZero # Digit5 :: Char
--- '5'
---
--- >>> charHEXADECIMALNoZero # Digit6 :: Char
--- '6'
---
--- >>> charHEXADECIMALNoZero # Digit7 :: Char
--- '7'
---
--- >>> charHEXADECIMALNoZero # Digit8 :: Char
--- '8'
---
--- >>> charHEXADECIMALNoZero # Digit9 :: Char
--- '9'
---
--- >>> charHEXADECIMALNoZero # DigitA :: Char
--- 'A'
---
--- >>> charHEXADECIMALNoZero # DigitB :: Char
--- 'B'
---
--- >>> charHEXADECIMALNoZero # DigitC :: Char
--- 'C'
---
--- >>> charHEXADECIMALNoZero # DigitD :: Char
--- 'D'
---
--- >>> charHEXADECIMALNoZero # DigitE :: Char
--- 'E'
+-- >>> 'F' ^? charHEXADECIMALNoZero :: Maybe HEXDigit
+-- Just HEXDigitF
 --
--- >>> charHEXADECIMALNoZero # DigitF :: Char
+-- >>> charHEXADECIMALNoZero # HEXDigitF :: Char
 -- 'F'
---
--- prop> \c -> (c `notElem` "123456789ABCDEF") ==> (c ^? charHEXADECIMALNoZero == Nothing)
 charHEXADECIMALNoZero ::
   HEXADECIMALNoZero d =>
   Prism'
@@ -648,104 +164,11 @@
   associatePrism ('1', d1) [('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('A', dA), ('B', dB), ('C', dC), ('D', dD), ('E', dE), ('F', dF)]
   
 -- |
---
--- >>> '0' ^? charHEXADECIMAL :: Maybe Digit
--- Just 0
---
--- >>> '1' ^? charHEXADECIMAL :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charHEXADECIMAL :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charHEXADECIMAL :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charHEXADECIMAL :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charHEXADECIMAL :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charHEXADECIMAL :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charHEXADECIMAL :: Maybe Digit
--- Just 7
---
--- >>> '8' ^? charHEXADECIMAL :: Maybe Digit
--- Just 8
---
--- >>> '9' ^? charHEXADECIMAL :: Maybe Digit
--- Just 9
---
--- >>> 'A' ^? charHEXADECIMAL :: Maybe Digit
--- Just A
---
--- >>> 'B' ^? charHEXADECIMAL :: Maybe Digit
--- Just B
---
--- >>> 'C' ^? charHEXADECIMAL :: Maybe Digit
--- Just C
---
--- >>> 'D' ^? charHEXADECIMAL :: Maybe Digit
--- Just D
---
--- >>> 'E' ^? charHEXADECIMAL :: Maybe Digit
--- Just E
---
--- >>> 'F' ^? charHEXADECIMAL :: Maybe Digit
--- Just F
---
--- >>> charHEXADECIMAL # Digit0 :: Char
--- '0'
---
--- >>> charHEXADECIMAL # Digit1 :: Char
--- '1'
---
--- >>> charHEXADECIMAL # Digit2 :: Char
--- '2'
---
--- >>> charHEXADECIMAL # Digit3 :: Char
--- '3'
---
--- >>> charHEXADECIMAL # Digit4 :: Char
--- '4'
---
--- >>> charHEXADECIMAL # Digit5 :: Char
--- '5'
---
--- >>> charHEXADECIMAL # Digit6 :: Char
--- '6'
---
--- >>> charHEXADECIMAL # Digit7 :: Char
--- '7'
---
--- >>> charHEXADECIMAL # Digit8 :: Char
--- '8'
---
--- >>> charHEXADECIMAL # Digit9 :: Char
--- '9'
---
--- >>> charHEXADECIMAL # DigitA :: Char
--- 'A'
---
--- >>> charHEXADECIMAL # DigitB :: Char
--- 'B'
---
--- >>> charHEXADECIMAL # DigitC :: Char
--- 'C'
---
--- >>> charHEXADECIMAL # DigitD :: Char
--- 'D'
---
--- >>> charHEXADECIMAL # DigitE :: Char
--- 'E'
+-- >>> 'F' ^? charHEXADECIMAL :: Maybe HEXDigit
+-- Just HEXDigitF
 --
--- >>> charHEXADECIMAL # DigitF :: Char
+-- >>> charHEXADECIMAL # HEXDigitF :: Char
 -- 'F'
---
--- prop> \c -> (c `notElem` "0123456789ABCDEF") ==> (c ^? charHEXADECIMAL == Nothing)
 charHEXADECIMAL ::
   HEXADECIMAL d =>
   Prism'
@@ -755,134 +178,17 @@
   associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('A', dA), ('B', dB), ('C', dC), ('D', dD), ('E', dE), ('F', dF)]
   
 -- |
---
--- >>> '1' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just 7
---
--- >>> '8' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just 8
---
--- >>> '9' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just 9
---
--- >>> 'a' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just a
---
--- >>> 'b' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just b
---
--- >>> 'c' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just c
---
--- >>> 'd' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just d
---
--- >>> 'e' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just e
---
--- >>> 'f' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just f
---
--- >>> 'A' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just A
---
--- >>> 'B' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just B
---
--- >>> 'C' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just C
---
--- >>> 'D' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just D
---
--- >>> 'E' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just E
---
--- >>> 'F' ^? charHeXaDeCiMaLNoZero :: Maybe Digit
--- Just F
---
--- >>> charHeXaDeCiMaLNoZero # Digit1 :: Char
--- '1'
---
--- >>> charHeXaDeCiMaLNoZero # Digit2 :: Char
--- '2'
---
--- >>> charHeXaDeCiMaLNoZero # Digit3 :: Char
--- '3'
---
--- >>> charHeXaDeCiMaLNoZero # Digit4 :: Char
--- '4'
---
--- >>> charHeXaDeCiMaLNoZero # Digit5 :: Char
--- '5'
---
--- >>> charHeXaDeCiMaLNoZero # Digit6 :: Char
--- '6'
---
--- >>> charHeXaDeCiMaLNoZero # Digit7 :: Char
--- '7'
---
--- >>> charHeXaDeCiMaLNoZero # Digit8 :: Char
--- '8'
---
--- >>> charHeXaDeCiMaLNoZero # Digit9 :: Char
--- '9'
---
--- >>> charHeXaDeCiMaLNoZero # Digita :: Char
--- 'a'
---
--- >>> charHeXaDeCiMaLNoZero # Digitb :: Char
--- 'b'
---
--- >>> charHeXaDeCiMaLNoZero # Digitc :: Char
--- 'c'
---
--- >>> charHeXaDeCiMaLNoZero # Digitd :: Char
--- 'd'
+-- >>> 'f' ^? charHeXaDeCiMaLNoZero :: Maybe HeXDigit
+-- Just HeXDigitf
 --
--- >>> charHeXaDeCiMaLNoZero # Digite :: Char
--- 'e'
+-- >>> 'F' ^? charHeXaDeCiMaLNoZero :: Maybe HeXDigit
+-- Just HeXDigitF
 --
--- >>> charHeXaDeCiMaLNoZero # Digitf :: Char
+-- >>> charHeXaDeCiMaLNoZero # HeXDigitf :: Char
 -- 'f'
 --
--- >>> charHeXaDeCiMaLNoZero # DigitA :: Char
--- 'A'
---
--- >>> charHeXaDeCiMaLNoZero # DigitB :: Char
--- 'B'
---
--- >>> charHeXaDeCiMaLNoZero # DigitC :: Char
--- 'C'
---
--- >>> charHeXaDeCiMaLNoZero # DigitD :: Char
--- 'D'
---
--- >>> charHeXaDeCiMaLNoZero # DigitE :: Char
--- 'E'
---
--- >>> charHeXaDeCiMaLNoZero # DigitF :: Char
+-- >>> charHeXaDeCiMaLNoZero # HeXDigitF :: Char
 -- 'F'
---
--- prop> \c -> (c `notElem` "123456789abcdefABCDEF") ==> (c ^? charHeXaDeCiMaLNoZero == Nothing)
 charHeXaDeCiMaLNoZero ::
   HeXaDeCiMaLNoZero d =>
   Prism'
@@ -893,140 +199,17 @@
   
 
 -- |
---
--- >>> '0' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 0
---
--- >>> '1' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 1
---
--- >>> '2' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 2
---
--- >>> '3' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 3
---
--- >>> '4' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 4
---
--- >>> '5' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 5
---
--- >>> '6' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 6
---
--- >>> '7' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 7
---
--- >>> '8' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 8
---
--- >>> '9' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just 9
---
--- >>> 'a' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just a
---
--- >>> 'b' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just b
---
--- >>> 'c' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just c
---
--- >>> 'd' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just d
---
--- >>> 'e' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just e
---
--- >>> 'f' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just f
---
--- >>> 'A' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just A
---
--- >>> 'B' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just B
---
--- >>> 'C' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just C
---
--- >>> 'D' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just D
---
--- >>> 'E' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just E
---
--- >>> 'F' ^? charHeXaDeCiMaL :: Maybe Digit
--- Just F
---
--- >>> charHeXaDeCiMaL # Digit0 :: Char
--- '0'
---
--- >>> charHeXaDeCiMaL # Digit1 :: Char
--- '1'
---
--- >>> charHeXaDeCiMaL # Digit2 :: Char
--- '2'
---
--- >>> charHeXaDeCiMaL # Digit3 :: Char
--- '3'
---
--- >>> charHeXaDeCiMaL # Digit4 :: Char
--- '4'
---
--- >>> charHeXaDeCiMaL # Digit5 :: Char
--- '5'
---
--- >>> charHeXaDeCiMaL # Digit6 :: Char
--- '6'
---
--- >>> charHeXaDeCiMaL # Digit7 :: Char
--- '7'
---
--- >>> charHeXaDeCiMaL # Digit8 :: Char
--- '8'
---
--- >>> charHeXaDeCiMaL # Digit9 :: Char
--- '9'
---
--- >>> charHeXaDeCiMaL # Digita :: Char
--- 'a'
---
--- >>> charHeXaDeCiMaL # Digitb :: Char
--- 'b'
---
--- >>> charHeXaDeCiMaL # Digitc :: Char
--- 'c'
---
--- >>> charHeXaDeCiMaL # Digitd :: Char
--- 'd'
+-- >>> 'f' ^? charHeXaDeCiMaL :: Maybe HeXDigit
+-- Just HeXDigitf
 --
--- >>> charHeXaDeCiMaL # Digite :: Char
--- 'e'
+-- >>> 'F' ^? charHeXaDeCiMaL :: Maybe HeXDigit
+-- Just HeXDigitF
 --
--- >>> charHeXaDeCiMaL # Digitf :: Char
+-- >>> charHeXaDeCiMaL # HeXDigitf :: Char
 -- 'f'
 --
--- >>> charHeXaDeCiMaL # DigitA :: Char
--- 'A'
---
--- >>> charHeXaDeCiMaL # DigitB :: Char
--- 'B'
---
--- >>> charHeXaDeCiMaL # DigitC :: Char
--- 'C'
---
--- >>> charHeXaDeCiMaL # DigitD :: Char
--- 'D'
---
--- >>> charHeXaDeCiMaL # DigitE :: Char
--- 'E'
---
--- >>> charHeXaDeCiMaL # DigitF :: Char
+-- >>> charHeXaDeCiMaL # HeXDigitF :: Char
 -- 'F'
---
--- prop> \c -> (c `notElem` "0123456789abcdefABCDEF") ==> (c ^? charHeXaDeCiMaL == Nothing)
 charHeXaDeCiMaL ::
   HeXaDeCiMaL d =>
   Prism'
@@ -1034,7 +217,7 @@
     d
 charHeXaDeCiMaL =
   associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('a', da), ('b', db), ('c', dc), ('d', dd), ('e', de), ('f', df), ('A', dA), ('B', dB), ('C', dC), ('D', dD), ('E', dE), ('F', dF)]
-  
+
 ---- not exported
 associatePrism ::
   (Eq b, Choice p, Applicative f) =>
diff --git a/src/Data/Digit/D0.hs b/src/Data/Digit/D0.hs
--- a/src/Data/Digit/D0.hs
+++ b/src/Data/Digit/D0.hs
@@ -6,12 +6,12 @@
 , parse0
 ) where
   
-import Data.Digit.Digit(Digit(Digit0))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -31,28 +31,16 @@
 
 -- |
 --
--- >>> parse (parse0 <* eof) "test" "0" :: Either ParseError Digit
--- Right 0
+-- >>> parse (parse0 <* eof) "test" "0" :: Either ParseError BinDigit
+-- Right BinDigit0
 --
--- >>> parse parse0 "test" "0xyz" :: Either ParseError Digit
--- Right 0
+-- >>> parse parse0 "test" "0xyz" :: Either ParseError BinDigit
+-- Right BinDigit0
 --
--- >>> isn't _Right (parse parse0 "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse0 "test" "xyz" :: Either ParseError BinDigit)
 -- True
---
--- prop> \c -> c /= '0' ==> isn't _Right (parse parse0 "test" [c] :: Either ParseError Digit)
 parse0 ::
   (D0 d, CharParsing p) =>
   p d
 parse0 =
   x0 <$ char '0' <?> "0"
-
-instance D0 Digit where
-  d0 =
-    prism'
-      (\() -> Digit0)
-      (\d ->  case d of
-                Digit0 ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/D1.hs b/src/Data/Digit/D1.hs
--- a/src/Data/Digit/D1.hs
+++ b/src/Data/Digit/D1.hs
@@ -5,12 +5,12 @@
 , parse1
 ) where
 
-import Data.Digit.Digit(Digit(Digit1))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
 
 -- |
 --
--- >>> parse (parse1 <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
+-- >>> parse (parse1 <* eof) "test" "1" :: Either ParseError BinDigit
+-- Right BinDigit1
 --
--- >>> parse parse1 "test" "1xyz" :: Either ParseError Digit
--- Right 1
+-- >>> parse parse1 "test" "1xyz" :: Either ParseError BinDigit
+-- Right BinDigit1
 --
--- >>> isn't _Right (parse parse1 "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse1 "test" "xyz" :: Either ParseError BinDigit)
 -- True
---
--- prop> \c -> c /= '1' ==> isn't _Right (parse parse1 "test" [c] :: Either ParseError Digit)
 parse1 ::
   (D1 d, CharParsing p) =>
   p d
 parse1 =
   x1 <$ char '1' <?> "1"
-  
-instance D1 Digit where
-  d1 =
-    prism'
-      (\() -> Digit1)
-      (\d ->  case d of
-                Digit1 ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/D2.hs b/src/Data/Digit/D2.hs
--- a/src/Data/Digit/D2.hs
+++ b/src/Data/Digit/D2.hs
@@ -5,12 +5,12 @@
 , parse2
 ) where
 
-import Data.Digit.Digit(Digit(Digit2))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,29 +30,16 @@
     
 -- |
 --
--- >>> parse (parse2 <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
+-- >>> parse (parse2 <* eof) "test" "2" :: Either ParseError DecDigit
+-- Right DecDigit2
 --
--- >>> parse parse2 "test" "2xyz" :: Either ParseError Digit
--- Right 2
+-- >>> parse parse2 "test" "2xyz" :: Either ParseError DecDigit
+-- Right DecDigit2
 --
--- >>> isn't _Right (parse parse2 "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse2 "test" "xyz" :: Either ParseError DecDigit)
 -- True
---
--- prop> \c -> c /= '2' ==> isn't _Right (parse parse2 "test" [c] :: Either ParseError Digit)
 parse2 ::
   (D2 d, CharParsing p) =>
   p d
 parse2 =
   x2 <$ char '2' <?> "2"
-
-instance D2 Digit where
-  d2 =
-    prism'
-      (\() -> Digit2)
-      (\d ->  case d of
-                Digit2 ->
-                  Just ()
-                _ ->
-                  Nothing)
-
diff --git a/src/Data/Digit/D3.hs b/src/Data/Digit/D3.hs
--- a/src/Data/Digit/D3.hs
+++ b/src/Data/Digit/D3.hs
@@ -5,12 +5,12 @@
 , parse3
 ) where
 
-import Data.Digit.Digit(Digit(Digit3))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
 
 -- |
 --
--- >>> parse (parse3 <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
+-- >>> parse (parse3 <* eof) "test" "3" :: Either ParseError DecDigit
+-- Right DecDigit3
 --
--- >>> parse parse3 "test" "3xyz" :: Either ParseError Digit
--- Right 3
+-- >>> parse parse3 "test" "3xyz" :: Either ParseError DecDigit
+-- Right DecDigit3
 --
--- >>> isn't _Right (parse parse3 "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse3 "test" "xyz" :: Either ParseError DecDigit)
 -- True
---
--- prop> \c -> c /= '3' ==> isn't _Right (parse parse3 "test" [c] :: Either ParseError Digit)
 parse3 ::
   (D3 d, CharParsing p) =>
   p d
 parse3 =
   x3 <$ char '3' <?> "3"
-
-instance D3 Digit where
-  d3 =
-    prism'
-      (\() -> Digit3)
-      (\d ->  case d of
-                Digit3 ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/D4.hs b/src/Data/Digit/D4.hs
--- a/src/Data/Digit/D4.hs
+++ b/src/Data/Digit/D4.hs
@@ -5,12 +5,12 @@
 , parse4
 ) where
 
-import Data.Digit.Digit(Digit(Digit4))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
    
 -- |
 --
--- >>> parse (parse4 <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parse4 "test" "4xyz" :: Either ParseError Digit
--- Right 4
+-- >>> parse (parse4 <* eof) "test" "4" :: Either ParseError DecDigit
+-- Right DecDigit4
 --
--- >>> isn't _Right (parse parse4 "test" "xyz" :: Either ParseError Digit)
--- True 
+-- >>> parse parse4 "test" "4xyz" :: Either ParseError DecDigit
+-- Right DecDigit4
 --
--- prop> \c -> c /= '4' ==> isn't _Right (parse parse4 "test" [c] :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse4 "test" "xyz" :: Either ParseError DecDigit)
+-- True
 parse4 ::
   (D4 d, CharParsing p) =>
   p d
 parse4 =
   x4 <$ char '4' <?> "4"
-
-instance D4 Digit where
-  d4 =
-    prism'
-      (\() -> Digit4)
-      (\d ->  case d of
-                Digit4 ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/D5.hs b/src/Data/Digit/D5.hs
--- a/src/Data/Digit/D5.hs
+++ b/src/Data/Digit/D5.hs
@@ -5,12 +5,12 @@
 , parse5
 ) where
 
-import Data.Digit.Digit(Digit(Digit5))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parse5 <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
+-- >>> parse (parse5 <* eof) "test" "5" :: Either ParseError DecDigit
+-- Right DecDigit5
 --
--- >>> parse parse5 "test" "5xyz" :: Either ParseError Digit
--- Right 5
+-- >>> parse parse5 "test" "5xyz" :: Either ParseError DecDigit
+-- Right DecDigit5
 --
--- >>> isn't _Right (parse parse5 "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse5 "test" "xyz" :: Either ParseError DecDigit)
 -- True
---
--- prop> \c -> c /= '5' ==> isn't _Right (parse parse5 "test" [c] :: Either ParseError Digit)
 parse5 ::
   (D5 d, CharParsing p) =>
   p d
 parse5 =
   x5 <$ char '5' <?> "5"
-
-instance D5 Digit where
-  d5 =
-    prism'
-      (\() -> Digit5)
-      (\d ->  case d of
-                Digit5 ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/D6.hs b/src/Data/Digit/D6.hs
--- a/src/Data/Digit/D6.hs
+++ b/src/Data/Digit/D6.hs
@@ -5,12 +5,12 @@
 , parse6
 ) where
 
-import Data.Digit.Digit(Digit(Digit6))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parse6 <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
+-- >>> parse (parse6 <* eof) "test" "6" :: Either ParseError DecDigit
+-- Right DecDigit6
 --
--- >>> parse parse6 "test" "6xyz" :: Either ParseError Digit
--- Right 6
+-- >>> parse parse6 "test" "6xyz" :: Either ParseError DecDigit
+-- Right DecDigit6
 --
--- >>> isn't _Right (parse parse6 "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse6 "test" "xyz" :: Either ParseError DecDigit)
 -- True
---
--- prop> \c -> c /= '6' ==> isn't _Right (parse parse6 "test" [c] :: Either ParseError Digit)
 parse6 ::
   (D6 d, CharParsing p) =>
   p d
 parse6 =
   x6 <$ char '6' <?> "6"
-
-instance D6 Digit where
-  d6 =
-    prism'
-      (\() -> Digit6)
-      (\d ->  case d of
-                Digit6 ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/D7.hs b/src/Data/Digit/D7.hs
--- a/src/Data/Digit/D7.hs
+++ b/src/Data/Digit/D7.hs
@@ -5,12 +5,12 @@
 , parse7
 ) where
 
-import Data.Digit.Digit(Digit(Digit7))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parse7 <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
+-- >>> parse (parse7 <* eof) "test" "7" :: Either ParseError DecDigit
+-- Right DecDigit7
 --
--- >>> parse parse7 "test" "7xyz" :: Either ParseError Digit
--- Right 7
+-- >>> parse parse7 "test" "7xyz" :: Either ParseError DecDigit
+-- Right DecDigit7
 --
--- >>> isn't _Right (parse parse7 "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse7 "test" "xyz" :: Either ParseError DecDigit)
 -- True
---
--- prop> \c -> c /= '7' ==> isn't _Right (parse parse7 "test" [c] :: Either ParseError Digit)
 parse7 ::
   (D7 d, CharParsing p) =>
   p d
 parse7 =
   x7 <$ char '7' <?> "7"
-
-instance D7 Digit where
-  d7 =
-    prism'
-      (\() -> Digit7)
-      (\d ->  case d of
-                Digit7 ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/D8.hs b/src/Data/Digit/D8.hs
--- a/src/Data/Digit/D8.hs
+++ b/src/Data/Digit/D8.hs
@@ -5,12 +5,12 @@
 , parse8
 ) where
 
-import Data.Digit.Digit(Digit(Digit8))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parse8 <* eof) "test" "8" :: Either ParseError Digit
--- Right 8
+-- >>> parse (parse8 <* eof) "test" "8" :: Either ParseError DecDigit
+-- Right DecDigit8
 --
--- >>> parse parse8 "test" "8xyz" :: Either ParseError Digit
--- Right 8
+-- >>> parse parse8 "test" "8xyz" :: Either ParseError DecDigit
+-- Right DecDigit8
 --
--- >>> isn't _Right (parse parse8 "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse8 "test" "xyz" :: Either ParseError DecDigit)
 -- True
---
--- prop> \c -> c /= '8' ==> isn't _Right (parse parse8 "test" [c] :: Either ParseError Digit)
 parse8 ::
   (D8 d, CharParsing p) =>
   p d
 parse8 =
   x8 <$ char '8' <?> "8"
-
-instance D8 Digit where
-  d8 =
-    prism'
-      (\() -> Digit8)
-      (\d ->  case d of
-                Digit8 ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/D9.hs b/src/Data/Digit/D9.hs
--- a/src/Data/Digit/D9.hs
+++ b/src/Data/Digit/D9.hs
@@ -5,12 +5,12 @@
 , parse9
 ) where
 
-import Data.Digit.Digit(Digit(Digit9))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parse9 <* eof) "test" "9" :: Either ParseError Digit
--- Right 9
+-- >>> parse (parse9 <* eof) "test" "9" :: Either ParseError DecDigit
+-- Right DecDigit9
 --
--- >>> parse parse9 "test" "9xyz" :: Either ParseError Digit
--- Right 9
+-- >>> parse parse9 "test" "9xyz" :: Either ParseError DecDigit
+-- Right DecDigit9
 --
--- >>> isn't _Right (parse parse9 "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parse9 "test" "xyz" :: Either ParseError DecDigit)
 -- True
---
--- prop> \c -> c /= '9' ==> isn't _Right (parse parse9 "test" [c] :: Either ParseError Digit)
 parse9 ::
   (D9 d, CharParsing p) =>
   p d
 parse9 =
   x9 <$ char '9' <?> "9"
-
-instance D9 Digit where
-  d9 =
-    prism'
-      (\() -> Digit9)
-      (\d ->  case d of
-                Digit9 ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/DA.hs b/src/Data/Digit/DA.hs
--- a/src/Data/Digit/DA.hs
+++ b/src/Data/Digit/DA.hs
@@ -5,12 +5,12 @@
 , parseA
 ) where
 
-import Data.Digit.Digit(Digit(DigitA))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
 
 -- |
 --
--- >>> parse (parseA <* eof) "test" "A" :: Either ParseError Digit
--- Right A
+-- >>> parse (parseA <* eof) "test" "A" :: Either ParseError HEXDigit
+-- Right HEXDigitA
 --
--- >>> parse parseA "test" "Axyz" :: Either ParseError Digit
--- Right A
+-- >>> parse parseA "test" "Axyz" :: Either ParseError HEXDigit
+-- Right HEXDigitA
 --
--- >>> isn't _Right (parse parseA "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseA "test" "xyz" :: Either ParseError HEXDigit)
 -- True
---
--- prop> \c -> c /= 'A' ==> isn't _Right (parse parseA "test" [c] :: Either ParseError Digit)
 parseA ::
   (DA d, CharParsing p) =>
   p d
 parseA =
   xA <$ char 'A' <?> "A"
-
-instance DA Digit where
-  dA =
-    prism'
-      (\() -> DigitA)
-      (\d ->  case d of
-                DigitA ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/DAa.hs b/src/Data/Digit/DAa.hs
--- a/src/Data/Digit/DAa.hs
+++ b/src/Data/Digit/DAa.hs
@@ -1,25 +1,25 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ConstraintKinds #-}
-{-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 
 module Data.Digit.DAa(
-  DAa
+  module Data.Digit.DA
+, module Data.Digit.Da
+, DAa
 , parseAa
 ) where
 
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.DA(DA, parseA)
-import Data.Digit.Da(Da, parsea)
+import Data.Digit.DA
+import Data.Digit.Da
 
 -- $setup
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
+-- >>> import Data.Digit
 -- >>> import Papa
 
 type DAa a =
@@ -27,22 +27,20 @@
   
 -- |
 --
--- >>> parse (parseAa <* eof) "test" "A" :: Either ParseError Digit
--- Right A
+-- >>> parse (parseAa <* eof) "test" "A" :: Either ParseError HeXDigit
+-- Right HeXDigitA
 --
--- >>> parse parseAa "test" "Axyz" :: Either ParseError Digit
--- Right A
+-- >>> parse parseAa "test" "Axyz" :: Either ParseError HeXDigit
+-- Right HeXDigitA
 --
--- >>> parse (parseAa <* eof) "test" "a" :: Either ParseError Digit
--- Right a
+-- >>> parse (parseAa <* eof) "test" "a" :: Either ParseError HeXDigit
+-- Right HeXDigita
 --
--- >>> parse parseAa "test" "axyz" :: Either ParseError Digit
--- Right a
+-- >>> parse parseAa "test" "axyz" :: Either ParseError HeXDigit
+-- Right HeXDigita
 --
--- >>> isn't _Right (parse parseAa "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseAa "test" "xyz" :: Either ParseError HeXDigit)
 -- True
---
--- prop> \c -> (c `notElem` "Aa") ==> isn't _Right (parse parseAa "test" [c] :: Either ParseError Digit)
 parseAa ::
   (DAa d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/DB.hs b/src/Data/Digit/DB.hs
--- a/src/Data/Digit/DB.hs
+++ b/src/Data/Digit/DB.hs
@@ -5,12 +5,12 @@
 , parseB
 ) where
 
-import Data.Digit.Digit(Digit(DigitB))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parseB <* eof) "test" "B" :: Either ParseError Digit
--- Right B
+-- >>> parse (parseB <* eof) "test" "B" :: Either ParseError HEXDigit
+-- Right HEXDigitB
 --
--- >>> parse parseB "test" "Bxyz" :: Either ParseError Digit
--- Right B
+-- >>> parse parseB "test" "Bxyz" :: Either ParseError HEXDigit
+-- Right HEXDigitB
 --
--- >>> isn't _Right (parse parseB "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseB "test" "xyz" :: Either ParseError HEXDigit)
 -- True
---
--- prop> \c -> c /= 'B' ==> isn't _Right (parse parseB "test" [c] :: Either ParseError Digit)
 parseB ::
   (DB d, CharParsing p) =>
   p d
 parseB =
   xB <$ char 'B' <?> "B"
-
-instance DB Digit where
-  dB =
-    prism'
-      (\() -> DigitB)
-      (\d ->  case d of
-                DigitB ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/DBb.hs b/src/Data/Digit/DBb.hs
--- a/src/Data/Digit/DBb.hs
+++ b/src/Data/Digit/DBb.hs
@@ -2,19 +2,21 @@
 {-# LANGUAGE ConstraintKinds #-}
 
 module Data.Digit.DBb(
-  DBb
+  module Data.Digit.DB
+, module Data.Digit.Db
+, DBb
 , parseBb
 ) where
 
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.DB(DB, parseB)
-import Data.Digit.Db(Db, parseb)
+import Data.Digit.DB
+import Data.Digit.Db
 
 -- $setup
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
+-- >>> import Data.Digit
 -- >>> import Papa
 
 type DBb a =
@@ -22,22 +24,20 @@
   
 -- |
 --
--- >>> parse (parseBb <* eof) "test" "B" :: Either ParseError Digit
--- Right B
+-- >>> parse (parseBb <* eof) "test" "B" :: Either ParseError HeXDigit
+-- Right HeXDigitB
 --
--- >>> parse parseBb "test" "Bxyz" :: Either ParseError Digit
--- Right B
+-- >>> parse parseBb "test" "Bxyz" :: Either ParseError HeXDigit
+-- Right HeXDigitB
 --
--- >>> parse (parseBb <* eof) "test" "b" :: Either ParseError Digit
--- Right b
+-- >>> parse (parseBb <* eof) "test" "b" :: Either ParseError HeXDigit
+-- Right HeXDigitb
 --
--- >>> parse parseBb "test" "bxyz" :: Either ParseError Digit
--- Right b
+-- >>> parse parseBb "test" "bxyz" :: Either ParseError HeXDigit
+-- Right HeXDigitb
 --
--- >>> isn't _Right (parse parseBb "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseBb "test" "xyz" :: Either ParseError HeXDigit)
 -- True
---
--- prop> \c -> (c `notElem` "Bb") ==> isn't _Right (parse parseBb "test" [c] :: Either ParseError Digit)
 parseBb ::
   (DBb d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/DC.hs b/src/Data/Digit/DC.hs
--- a/src/Data/Digit/DC.hs
+++ b/src/Data/Digit/DC.hs
@@ -5,12 +5,12 @@
 , parseC
 ) where
 
-import Data.Digit.Digit(Digit(DigitC))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parseC <* eof) "test" "C" :: Either ParseError Digit
--- Right C
+-- >>> parse (parseC <* eof) "test" "C" :: Either ParseError HEXDigit
+-- Right HEXDigitC
 --
--- >>> parse parseC "test" "Cxyz" :: Either ParseError Digit
--- Right C
+-- >>> parse parseC "test" "Cxyz" :: Either ParseError HEXDigit
+-- Right HEXDigitC
 --
--- >>> isn't _Right (parse parseC "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseC "test" "xyz" :: Either ParseError HEXDigit)
 -- True
---
--- prop> \c -> c /= 'C' ==> isn't _Right (parse parseC "test" [c] :: Either ParseError Digit)
 parseC ::
   (DC d, CharParsing p) =>
   p d
 parseC =
   xC <$ char 'C' <?> "C"
-
-instance DC Digit where
-  dC =
-    prism'
-      (\() -> DigitC)
-      (\d ->  case d of
-                DigitC ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/DCc.hs b/src/Data/Digit/DCc.hs
--- a/src/Data/Digit/DCc.hs
+++ b/src/Data/Digit/DCc.hs
@@ -2,19 +2,21 @@
 {-# LANGUAGE ConstraintKinds #-}
 
 module Data.Digit.DCc(
-  DCc
+  module Data.Digit.DC
+, module Data.Digit.Dc
+, DCc
 , parseCc
 ) where
 
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.DC(DC, parseC)
-import Data.Digit.Dc(Dc, parsec)
+import Data.Digit.DC
+import Data.Digit.Dc
 
 -- $setup
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
+-- >>> import Data.Digit
 -- >>> import Papa
 
 type DCc a =
@@ -22,22 +24,20 @@
   
 -- |
 --
--- >>> parse (parseCc <* eof) "test" "C" :: Either ParseError Digit
--- Right C
+-- >>> parse (parseCc <* eof) "test" "C" :: Either ParseError HeXDigit
+-- Right HeXDigitC
 --
--- >>> parse parseCc "test" "Cxyz" :: Either ParseError Digit
--- Right C
+-- >>> parse parseCc "test" "Cxyz" :: Either ParseError HeXDigit
+-- Right HeXDigitC
 --
--- >>> parse (parseCc <* eof) "test" "c" :: Either ParseError Digit
--- Right c
+-- >>> parse (parseCc <* eof) "test" "c" :: Either ParseError HeXDigit
+-- Right HeXDigitc
 --
--- >>> parse parseCc "test" "cxyz" :: Either ParseError Digit
--- Right c
+-- >>> parse parseCc "test" "cxyz" :: Either ParseError HeXDigit
+-- Right HeXDigitc
 --
--- >>> isn't _Right (parse parseCc "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseCc "test" "xyz" :: Either ParseError HeXDigit)
 -- True
---
--- prop> \c -> (c `notElem` "Cc") ==> isn't _Right (parse parseCc "test" [c] :: Either ParseError Digit)
 parseCc ::
   (DCc d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/DD.hs b/src/Data/Digit/DD.hs
--- a/src/Data/Digit/DD.hs
+++ b/src/Data/Digit/DD.hs
@@ -5,12 +5,12 @@
 , parseD
 ) where
 
-import Data.Digit.Digit(Digit(DigitD))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parseD <* eof) "test" "D" :: Either ParseError Digit
--- Right D
+-- >>> parse (parseD <* eof) "test" "D" :: Either ParseError HEXDigit
+-- Right HEXDigitD
 --
--- >>> parse parseD "test" "Dxyz" :: Either ParseError Digit
--- Right D
+-- >>> parse parseD "test" "Dxyz" :: Either ParseError HEXDigit
+-- Right HEXDigitD
 --
--- >>> isn't _Right (parse parseD "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseD "test" "xyz" :: Either ParseError HEXDigit)
 -- True
---
--- prop> \c -> c /= 'D' ==> isn't _Right (parse parseD "test" [c] :: Either ParseError Digit)
 parseD ::
   (DD d, CharParsing p) =>
   p d
 parseD =
   xD <$ char 'D' <?> "D"
-
-instance DD Digit where
-  dD =
-    prism'
-      (\() -> DigitD)
-      (\d ->  case d of
-                DigitD ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/DDd.hs b/src/Data/Digit/DDd.hs
--- a/src/Data/Digit/DDd.hs
+++ b/src/Data/Digit/DDd.hs
@@ -2,19 +2,21 @@
 {-# LANGUAGE ConstraintKinds #-}
 
 module Data.Digit.DDd(
-  DDd
+  module Data.Digit.DD
+, module Data.Digit.Dd
+, DDd
 , parseDd
 ) where
 
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.DD(DD, parseD)
-import Data.Digit.Dd(Dd, parsed)
+import Data.Digit.DD
+import Data.Digit.Dd
 
 -- $setup
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
+-- >>> import Data.Digit
 -- >>> import Papa
 
 type DDd a =
@@ -22,22 +24,20 @@
   
 -- |
 --
--- >>> parse (parseDd <* eof) "test" "D" :: Either ParseError Digit
--- Right D
+-- >>> parse (parseDd <* eof) "test" "D" :: Either ParseError HeXDigit
+-- Right HeXDigitD
 --
--- >>> parse parseDd "test" "Dxyz" :: Either ParseError Digit
--- Right D
+-- >>> parse parseDd "test" "Dxyz" :: Either ParseError HeXDigit
+-- Right HeXDigitD
 --
--- >>> parse (parseDd <* eof) "test" "d" :: Either ParseError Digit
--- Right d
+-- >>> parse (parseDd <* eof) "test" "d" :: Either ParseError HeXDigit
+-- Right HeXDigitd
 --
--- >>> parse parseDd "test" "dxyz" :: Either ParseError Digit
--- Right d
+-- >>> parse parseDd "test" "dxyz" :: Either ParseError HeXDigit
+-- Right HeXDigitd
 --
--- >>> isn't _Right (parse parseDd "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseDd "test" "xyz" :: Either ParseError HeXDigit)
 -- True
---
--- prop> \c -> (c `notElem` "Dd") ==> isn't _Right (parse parseDd "test" [c] :: Either ParseError Digit)
 parseDd ::
   (DDd d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/DE.hs b/src/Data/Digit/DE.hs
--- a/src/Data/Digit/DE.hs
+++ b/src/Data/Digit/DE.hs
@@ -5,12 +5,12 @@
 , parseE
 ) where
 
-import Data.Digit.Digit(Digit(DigitE))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parseE <* eof) "test" "E" :: Either ParseError Digit
--- Right E
+-- >>> parse (parseE <* eof) "test" "E" :: Either ParseError HEXDigit
+-- Right HEXDigitE
 --
--- >>> parse parseE "test" "Exyz" :: Either ParseError Digit
--- Right E
+-- >>> parse parseE "test" "Exyz" :: Either ParseError HEXDigit
+-- Right HEXDigitE
 --
--- >>> isn't _Right (parse parseE "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseE "test" "xyz" :: Either ParseError HEXDigit)
 -- True
---
--- prop> \c -> c /= 'E' ==> isn't _Right (parse parseE "test" [c] :: Either ParseError Digit)
 parseE ::
   (DE d, CharParsing p) =>
   p d
 parseE =
   xE <$ char 'E' <?> "E"
-
-instance DE Digit where
-  dE =
-    prism'
-      (\() -> DigitE)
-      (\d ->  case d of
-                DigitE ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/DEe.hs b/src/Data/Digit/DEe.hs
--- a/src/Data/Digit/DEe.hs
+++ b/src/Data/Digit/DEe.hs
@@ -2,14 +2,16 @@
 {-# LANGUAGE ConstraintKinds #-}
 
 module Data.Digit.DEe(
-  DEe
+  module Data.Digit.DE
+, module Data.Digit.De
+, DEe
 , parseEe
 ) where
 
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.DE(DE, parseE)
-import Data.Digit.De(De, parsee)
+import Data.Digit.DE
+import Data.Digit.De
 
 -- $setup
 -- >>> import Text.Parsec(parse, ParseError, eof)
@@ -22,22 +24,20 @@
   
 -- |
 --
--- >>> parse (parseEe <* eof) "test" "E" :: Either ParseError Digit
--- Right E
+-- >>> parse (parseEe <* eof) "test" "E" :: Either ParseError HeXDigit
+-- Right HeXDigitE
 --
--- >>> parse parseEe "test" "Exyz" :: Either ParseError Digit
--- Right E
+-- >>> parse parseEe "test" "Exyz" :: Either ParseError HeXDigit
+-- Right HeXDigitE
 --
--- >>> parse (parseEe <* eof) "test" "e" :: Either ParseError Digit
--- Right e
+-- >>> parse (parseEe <* eof) "test" "e" :: Either ParseError HeXDigit
+-- Right HeXDigite
 --
--- >>> parse parseEe "test" "exyz" :: Either ParseError Digit
--- Right e
+-- >>> parse parseEe "test" "exyz" :: Either ParseError HeXDigit
+-- Right HeXDigite
 --
--- >>> isn't _Right (parse parseEe "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseEe "test" "xyz" :: Either ParseError HeXDigit)
 -- True
---
--- prop> \c -> (c `notElem` "Ee") ==> isn't _Right (parse parseEe "test" [c] :: Either ParseError Digit)
 parseEe ::
   (DEe d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/DF.hs b/src/Data/Digit/DF.hs
--- a/src/Data/Digit/DF.hs
+++ b/src/Data/Digit/DF.hs
@@ -5,12 +5,12 @@
 , parseF
 ) where
 
-import Data.Digit.Digit(Digit(DigitF))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parseF <* eof) "test" "F" :: Either ParseError Digit
--- Right F
+-- >>> parse (parseF <* eof) "test" "F" :: Either ParseError HEXDigit
+-- Right HEXDigitF
 --
--- >>> parse parseF "test" "Fxyz" :: Either ParseError Digit
--- Right F
+-- >>> parse parseF "test" "Fxyz" :: Either ParseError HEXDigit
+-- Right HEXDigitF
 --
--- >>> isn't _Right (parse parseF "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseF "test" "xyz" :: Either ParseError HEXDigit)
 -- True
---
--- prop> \c -> c /= 'F' ==> isn't _Right (parse parseF "test" [c] :: Either ParseError Digit)
 parseF ::
   (DF d, CharParsing p) =>
   p d
 parseF =
   xF <$ char 'F' <?> "F"
-
-instance DF Digit where
-  dF =
-    prism'
-      (\() -> DigitF)
-      (\d ->  case d of
-                DigitF ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/DFf.hs b/src/Data/Digit/DFf.hs
--- a/src/Data/Digit/DFf.hs
+++ b/src/Data/Digit/DFf.hs
@@ -2,19 +2,21 @@
 {-# LANGUAGE ConstraintKinds #-}
 
 module Data.Digit.DFf(
-  DFf
+  module Data.Digit.DF
+, module Data.Digit.Df
+, DFf
 , parseFf
 ) where
 
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.DF(DF, parseF)
-import Data.Digit.Df(Df, parsef)
+import Data.Digit.DF
+import Data.Digit.Df
 
 -- $setup
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
+-- >>> import Data.Digit
 -- >>> import Papa
 
 type DFf a =
@@ -22,22 +24,20 @@
   
 -- |
 --
--- >>> parse (parseFf <* eof) "test" "F" :: Either ParseError Digit
--- Right F
+-- >>> parse (parseFf <* eof) "test" "F" :: Either ParseError HeXDigit
+-- Right HeXDigitF
 --
--- >>> parse parseFf "test" "Fxyz" :: Either ParseError Digit
--- Right F
+-- >>> parse parseFf "test" "Fxyz" :: Either ParseError HeXDigit
+-- Right HeXDigitF
 --
--- >>> parse (parseFf <* eof) "test" "f" :: Either ParseError Digit
--- Right f
+-- >>> parse (parseFf <* eof) "test" "f" :: Either ParseError HeXDigit
+-- Right HeXDigitf
 --
--- >>> parse parseFf "test" "fxyz" :: Either ParseError Digit
--- Right f
+-- >>> parse parseFf "test" "fxyz" :: Either ParseError HeXDigit
+-- Right HeXDigitf
 --
--- >>> isn't _Right (parse parseFf "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseFf "test" "xyz" :: Either ParseError HeXDigit)
 -- True
---
--- prop> \c -> (c `notElem` "Ff") ==> isn't _Right (parse parseFf "test" [c] :: Either ParseError Digit)
 parseFf ::
   (DFf d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/Da.hs b/src/Data/Digit/Da.hs
--- a/src/Data/Digit/Da.hs
+++ b/src/Data/Digit/Da.hs
@@ -5,12 +5,12 @@
 , parsea
 ) where
 
-import Data.Digit.Digit(Digit(Digita))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parsea <* eof) "test" "a" :: Either ParseError Digit
--- Right a
+-- >>> parse (parsea <* eof) "test" "a" :: Either ParseError HexDigit
+-- Right HexDigita
 --
--- >>> parse parsea "test" "axyz" :: Either ParseError Digit
--- Right a
+-- >>> parse parsea "test" "axyz" :: Either ParseError HexDigit
+-- Right HexDigita
 --
--- >>> isn't _Right (parse parsea "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parsea "test" "xyz" :: Either ParseError HexDigit)
 -- True
---
--- prop> \c -> c /= 'a' ==> isn't _Right (parse parsea "test" [c] :: Either ParseError Digit)
 parsea ::
   (Da d, CharParsing p) =>
   p d
 parsea =
   xa <$ char 'a' <?> "a"
-
-instance Da Digit where
-  da =
-    prism'
-      (\() -> Digita)
-      (\d ->  case d of
-                Digita ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/Db.hs b/src/Data/Digit/Db.hs
--- a/src/Data/Digit/Db.hs
+++ b/src/Data/Digit/Db.hs
@@ -5,12 +5,12 @@
 , parseb
 ) where
 
-import Data.Digit.Digit(Digit(Digitb))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parseb <* eof) "test" "b" :: Either ParseError Digit
--- Right b
+-- >>> parse (parseb <* eof) "test" "b" :: Either ParseError HexDigit
+-- Right HexDigitb
 --
--- >>> parse parseb "test" "bxyz" :: Either ParseError Digit
--- Right b
+-- >>> parse parseb "test" "bxyz" :: Either ParseError HexDigit
+-- Right HexDigitb
 --
--- >>> isn't _Right (parse parseb "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parseb "test" "xyz" :: Either ParseError HexDigit)
 -- True
---
--- prop> \c -> c /= 'b' ==> isn't _Right (parse parseb "test" [c] :: Either ParseError Digit)
 parseb ::
   (Db d, CharParsing p) =>
   p d
 parseb =
   xb <$ char 'b' <?> "b"
-
-instance Db Digit where
-  db =
-    prism'
-      (\() -> Digitb)
-      (\d ->  case d of
-                Digitb ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/Dc.hs b/src/Data/Digit/Dc.hs
--- a/src/Data/Digit/Dc.hs
+++ b/src/Data/Digit/Dc.hs
@@ -5,12 +5,12 @@
 , parsec
 ) where
 
-import Data.Digit.Digit(Digit(Digitc))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
    
 -- |
 --
--- >>> parse (parsec <* eof) "test" "c" :: Either ParseError Digit
--- Right c
+-- >>> parse (parsec <* eof) "test" "c" :: Either ParseError HexDigit
+-- Right HexDigitc
 --
--- >>> parse parsec "test" "cxyz" :: Either ParseError Digit
--- Right c
+-- >>> parse parsec "test" "cxyz" :: Either ParseError HexDigit
+-- Right HexDigitc
 --
--- >>> isn't _Right (parse parsec "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parsec "test" "xyz" :: Either ParseError HexDigit)
 -- True
---
--- prop> \c -> c /= 'c' ==> isn't _Right (parse parsec "test" [c] :: Either ParseError Digit)
 parsec ::
   (Dc d, CharParsing p) =>
   p d
 parsec =
   xc <$ char 'c' <?> "c"
-
-instance Dc Digit where
-  dc =
-    prism'
-      (\() -> Digitc)
-      (\d ->  case d of
-                Digitc ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/Dd.hs b/src/Data/Digit/Dd.hs
--- a/src/Data/Digit/Dd.hs
+++ b/src/Data/Digit/Dd.hs
@@ -5,12 +5,12 @@
 , parsed
 ) where
 
-import Data.Digit.Digit(Digit(Digitd))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,29 +30,16 @@
     
 -- |
 --
--- >>> parse (parsed <* eof) "test" "d" :: Either ParseError Digit
--- Right d
+-- >>> parse (parsed <* eof) "test" "d" :: Either ParseError HexDigit
+-- Right HexDigitd
 --
--- >>> parse parsed "test" "dxyz" :: Either ParseError Digit
--- Right d
+-- >>> parse parsed "test" "dxyz" :: Either ParseError HexDigit
+-- Right HexDigitd
 --
--- >>> isn't _Right (parse parsed "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parsed "test" "xyz" :: Either ParseError HexDigit)
 -- True
---
--- prop> \c -> c /= 'd' ==> isn't _Right (parse parsed "test" [c] :: Either ParseError Digit)
 parsed ::
   (Dd d, CharParsing p) =>
   p d
 parsed =
   xd <$ char 'd' <?> "d"
-
-instance Dd Digit where
-  dd =
-    prism'
-      (\() -> Digitd)
-      (\d ->  case d of
-                Digitd ->
-                  Just ()
-                _ ->
-                  Nothing)
-
diff --git a/src/Data/Digit/De.hs b/src/Data/Digit/De.hs
--- a/src/Data/Digit/De.hs
+++ b/src/Data/Digit/De.hs
@@ -5,12 +5,12 @@
 , parsee
 ) where
 
-import Data.Digit.Digit(Digit(Digite))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parsee <* eof) "test" "e" :: Either ParseError Digit
--- Right e
+-- >>> parse (parsee <* eof) "test" "e" :: Either ParseError HexDigit
+-- Right HexDigite
 --
--- >>> parse parsee "test" "exyz" :: Either ParseError Digit
--- Right e
+-- >>> parse parsee "test" "exyz" :: Either ParseError HexDigit
+-- Right HexDigite
 --
--- >>> isn't _Right (parse parsee "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parsee "test" "xyz" :: Either ParseError HexDigit)
 -- True
---
--- prop> \c -> c /= 'e' ==> isn't _Right (parse parsee "test" [c] :: Either ParseError Digit)
 parsee ::
   (De d, CharParsing p) =>
   p d
 parsee =
   xe <$ char 'e' <?> "e"
-
-instance De Digit where
-  de =
-    prism'
-      (\() -> Digite)
-      (\d ->  case d of
-                Digite ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/Decimal.hs b/src/Data/Digit/Decimal.hs
--- a/src/Data/Digit/Decimal.hs
+++ b/src/Data/Digit/Decimal.hs
@@ -1,95 +1,81 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 module Data.Digit.Decimal(
-  DecimalNoZero
+  DecDigit(..)
+, DecimalNoZero
 , Decimal
 , parseDecimalNoZero
 , parseDecimal
+-- * Prisms
+, _DecDigit0
+, _DecDigit1
+, _DecDigit2
+, _DecDigit3
+, _DecDigit4
+, _DecDigit5
+, _DecDigit6
+, _DecDigit7
+, _DecDigit8
+, _DecDigit9
+-- * Re-exports
+, module Data.Digit.D0
+, module Data.Digit.D1
+, module Data.Digit.D2
+, module Data.Digit.D3
+, module Data.Digit.D4
+, module Data.Digit.D5
+, module Data.Digit.D6
+, module Data.Digit.D7
+, module Data.Digit.D8
+, module Data.Digit.D9
 ) where
 
+import Prelude (Eq, Show, Ord, Enum, Bounded)
+import Control.Lens.TH (makePrisms)
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.D0(D0, parse0)
-import Data.Digit.D1(D1, parse1)
-import Data.Digit.D2(D2, parse2)
-import Data.Digit.D3(D3, parse3)
-import Data.Digit.D4(D4, parse4)
-import Data.Digit.D5(D5, parse5)
-import Data.Digit.D6(D6, parse6)
-import Data.Digit.D7(D7, parse7)
-import Data.Digit.D8(D8, parse8)
-import Data.Digit.D9(D9, parse9)
+import Data.Digit.D0
+import Data.Digit.D1
+import Data.Digit.D2
+import Data.Digit.D3
+import Data.Digit.D4
+import Data.Digit.D5
+import Data.Digit.D6
+import Data.Digit.D7
+import Data.Digit.D8
+import Data.Digit.D9
 
--- $setup
--- >>> import Text.Parsec(parse, ParseError, eof)
--- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
--- >>> import Papa
+data DecDigit
+  = DecDigit0
+  | DecDigit1
+  | DecDigit2
+  | DecDigit3
+  | DecDigit4
+  | DecDigit5
+  | DecDigit6
+  | DecDigit7
+  | DecDigit8
+  | DecDigit9
+  deriving (Show, Eq, Ord, Enum, Bounded)
 
+makePrisms ''DecDigit
+
+instance D0 DecDigit where; d0 = _DecDigit0
+instance D1 DecDigit where; d1 = _DecDigit1
+instance D2 DecDigit where; d2 = _DecDigit2
+instance D3 DecDigit where; d3 = _DecDigit3
+instance D4 DecDigit where; d4 = _DecDigit4
+instance D5 DecDigit where; d5 = _DecDigit5
+instance D6 DecDigit where; d6 = _DecDigit6
+instance D7 DecDigit where; d7 = _DecDigit7
+instance D8 DecDigit where; d8 = _DecDigit8
+instance D9 DecDigit where; d9 = _DecDigit9
+
 type DecimalNoZero d =
   (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d, D8 d, D9 d)
 
--- |
---
--- >>> parse (parseDecimalNoZero <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseDecimalNoZero "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseDecimalNoZero <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseDecimalNoZero "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseDecimalNoZero <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseDecimalNoZero "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseDecimalNoZero <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseDecimalNoZero "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseDecimalNoZero <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseDecimalNoZero "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseDecimalNoZero <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseDecimalNoZero "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseDecimalNoZero <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseDecimalNoZero "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> parse (parseDecimalNoZero <* eof) "test" "8" :: Either ParseError Digit
--- Right 8
---
--- >>> parse parseDecimalNoZero "test" "8xyz" :: Either ParseError Digit
--- Right 8
---
--- >>> parse (parseDecimalNoZero <* eof) "test" "9" :: Either ParseError Digit
--- Right 9
---
--- >>> parse parseDecimalNoZero "test" "9xyz" :: Either ParseError Digit
--- Right 9
---
--- >>> isn't _Right (parse parseDecimalNoZero "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "123456789") ==> isn't _Right (parse parseDecimalNoZero "test" [c] :: Either ParseError Digit)
 parseDecimalNoZero ::
   (DecimalNoZero d, CharParsing p) =>
   p d
@@ -110,72 +96,6 @@
 type Decimal d =
   (D0 d, DecimalNoZero d)
 
--- |
---
--- >>> parse (parseDecimal <* eof) "test" "0" :: Either ParseError Digit
--- Right 0
---
--- >>> parse parseDecimal "test" "0xyz" :: Either ParseError Digit
--- Right 0
---
--- >>> parse (parseDecimal <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseDecimal "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseDecimal <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseDecimal "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseDecimal <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseDecimal "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseDecimal <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseDecimal "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseDecimal <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseDecimal "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseDecimal <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseDecimal "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseDecimal <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseDecimal "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> parse (parseDecimal <* eof) "test" "8" :: Either ParseError Digit
--- Right 8
---
--- >>> parse parseDecimal "test" "8xyz" :: Either ParseError Digit
--- Right 8
---
--- >>> parse (parseDecimal <* eof) "test" "9" :: Either ParseError Digit
--- Right 9
---
--- >>> parse parseDecimal "test" "9xyz" :: Either ParseError Digit
--- Right 9
---
--- >>> isn't _Right (parse parseDecimal "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "0123456789") ==> isn't _Right (parse parseDecimal "test" [c] :: Either ParseError Digit)
 parseDecimal ::
   (Decimal d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/Df.hs b/src/Data/Digit/Df.hs
--- a/src/Data/Digit/Df.hs
+++ b/src/Data/Digit/Df.hs
@@ -5,12 +5,12 @@
 , parsef
 ) where
 
-import Data.Digit.Digit(Digit(Digitf))
 import Papa
 import Text.Parser.Char(CharParsing, char)
 import Text.Parser.Combinators((<?>))
 
 -- $setup
+-- >>> import Data.Digit
 -- >>> import Text.Parsec(parse, ParseError, eof)
 -- >>> import Data.Void(Void)
 
@@ -30,28 +30,16 @@
     
 -- |
 --
--- >>> parse (parsef <* eof) "test" "f" :: Either ParseError Digit
--- Right f
+-- >>> parse (parsef <* eof) "test" "f" :: Either ParseError HexDigit
+-- Right HexDigitf
 --
--- >>> parse parsef "test" "fxyz" :: Either ParseError Digit
--- Right f
+-- >>> parse parsef "test" "fxyz" :: Either ParseError HexDigit
+-- Right HexDigitf
 --
--- >>> isn't _Right (parse parsef "test" "xyz" :: Either ParseError Digit)
+-- >>> isn't _Right (parse parsef "test" "xyz" :: Either ParseError HexDigit)
 -- True
---
--- prop> \c -> c /= 'f' ==> isn't _Right (parse parsef "test" [c] :: Either ParseError Digit)
 parsef ::
   (Df d, CharParsing p) =>
   p d
 parsef =
   xf <$ char 'f' <?> "f"
-
-instance Df Digit where
-  df =
-    prism'
-      (\() -> Digitf)
-      (\d ->  case d of
-                Digitf ->
-                  Just ()
-                _ ->
-                  Nothing)
diff --git a/src/Data/Digit/Digit.hs b/src/Data/Digit/Digit.hs
deleted file mode 100644
--- a/src/Data/Digit/Digit.hs
+++ /dev/null
@@ -1,78 +0,0 @@
-{-# LANGUAGE NoImplicitPrelude #-}
-
-module Data.Digit.Digit(
-  Digit(..)
-) where
-
-import Papa
-
-data Digit =
-  Digit0
-  | Digit1
-  | Digit2
-  | Digit3
-  | Digit4
-  | Digit5
-  | Digit6
-  | Digit7
-  | Digit8
-  | Digit9
-  | Digita
-  | Digitb
-  | Digitc
-  | Digitd
-  | Digite
-  | Digitf
-  | DigitA
-  | DigitB
-  | DigitC
-  | DigitD
-  | DigitE
-  | DigitF
-  deriving (Eq, Ord)
-
-instance Show Digit where
-  show Digit0 =
-    "0"
-  show Digit1 =
-    "1"
-  show Digit2 =
-    "2"
-  show Digit3 =
-    "3"
-  show Digit4 =
-    "4"
-  show Digit5 =
-    "5"
-  show Digit6 =
-    "6"
-  show Digit7 =
-    "7"
-  show Digit8 =
-    "8"
-  show Digit9 =
-    "9"
-  show Digita =
-    "a"
-  show Digitb =
-    "b"
-  show Digitc =
-    "c"
-  show Digitd =
-    "d"
-  show Digite =
-    "e"
-  show Digitf =
-    "f"
-  show DigitA =
-    "A"
-  show DigitB =
-    "B"
-  show DigitC =
-    "C"
-  show DigitD =
-    "D"
-  show DigitE =
-    "E"
-  show DigitF =
-    "F"
diff --git a/src/Data/Digit/Enum.hs b/src/Data/Digit/Enum.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Digit/Enum.hs
@@ -0,0 +1,169 @@
+module Data.Digit.Enum
+  ( -- * Binary
+    enumBinaryNoZero
+  , enumBinary
+    -- * Octal
+  , enumOctalNoZero
+  , enumOctal
+    -- * Decimal
+  , enumDecimalNoZero
+  , enumDecimal
+    -- * Hexadecimal
+  , enumHexadecimalNoZero
+  , enumHexadecimal
+    -- * HEXADECIMAL
+  , enumHEXADECIMALNoZero
+  , enumHEXADECIMAL
+  )
+where
+
+import Control.Lens.Review ((#))
+import Data.Digit.Binary
+import Data.Digit.Decimal
+import Data.Digit.Hexadecimal
+import Data.Digit.HEXADECIMAL
+import Data.Digit.Octal
+
+-- | @[1]@
+enumBinaryNoZero :: BinaryNoZero d => [d]
+enumBinaryNoZero = [d1 # ()]
+
+-- | @[0, 1]@
+enumBinary :: Binary d => [d]
+enumBinary = [d0 # (), d1 # ()]
+
+-- | @[1..7]@
+enumOctalNoZero :: OctalNoZero d => [d]
+enumOctalNoZero =
+  [ d1 # ()
+  , d2 # ()
+  , d3 # ()
+  , d4 # ()
+  , d5 # ()
+  , d6 # ()
+  , d7 # ()
+  ]
+
+-- | @[0..7]@
+enumOctal :: Octal d => [d]
+enumOctal =
+  [ d0 # ()
+  , d1 # ()
+  , d2 # ()
+  , d3 # ()
+  , d4 # ()
+  , d5 # ()
+  , d6 # ()
+  , d7 # ()
+  ]
+
+-- | @[1..9]@
+enumDecimalNoZero :: DecimalNoZero d => [d]
+enumDecimalNoZero =
+  [ d1 # ()
+  , d2 # ()
+  , d3 # ()
+  , d4 # ()
+  , d5 # ()
+  , d6 # ()
+  , d7 # ()
+  , d8 # ()
+  , d9 # ()
+  ]
+
+-- | @[0..9]@
+enumDecimal :: Decimal d => [d]
+enumDecimal =
+  [ d0 # ()
+  , d1 # ()
+  , d2 # ()
+  , d3 # ()
+  , d4 # ()
+  , d5 # ()
+  , d6 # ()
+  , d7 # ()
+  , d8 # ()
+  , d9 # ()
+  ]
+
+-- | @[1..9] ++ [a..f]@
+enumHexadecimalNoZero :: HexadecimalNoZero d => [d]
+enumHexadecimalNoZero =
+  [ d1 # ()
+  , d2 # ()
+  , d3 # ()
+  , d4 # ()
+  , d5 # ()
+  , d6 # ()
+  , d7 # ()
+  , d8 # ()
+  , d9 # ()
+  , da # ()
+  , db # ()
+  , dc # ()
+  , dd # ()
+  , de # ()
+  , df # ()
+  ]
+
+-- | @[0..9] ++ [a..f]@
+enumHexadecimal :: Hexadecimal d => [d]
+enumHexadecimal =
+  [ d0 # ()
+  , d1 # ()
+  , d2 # ()
+  , d3 # ()
+  , d4 # ()
+  , d5 # ()
+  , d6 # ()
+  , d7 # ()
+  , d8 # ()
+  , d9 # ()
+  , da # ()
+  , db # ()
+  , dc # ()
+  , dd # ()
+  , de # ()
+  , df # ()
+  ]
+
+-- | @[1..9] ++ [A..F]@
+enumHEXADECIMALNoZero :: HEXADECIMALNoZero d => [d]
+enumHEXADECIMALNoZero =
+  [ d1 # ()
+  , d2 # ()
+  , d3 # ()
+  , d4 # ()
+  , d5 # ()
+  , d6 # ()
+  , d7 # ()
+  , d8 # ()
+  , d9 # ()
+  , dA # ()
+  , dB # ()
+  , dC # ()
+  , dD # ()
+  , dE # ()
+  , dF # ()
+  ]
+
+-- | @[0..9] ++ [A..F]@
+enumHEXADECIMAL :: HEXADECIMAL d => [d]
+enumHEXADECIMAL =
+  [ d0 # ()
+  , d1 # ()
+  , d2 # ()
+  , d3 # ()
+  , d4 # ()
+  , d5 # ()
+  , d6 # ()
+  , d7 # ()
+  , d8 # ()
+  , d9 # ()
+  , dA # ()
+  , dB # ()
+  , dC # ()
+  , dD # ()
+  , dE # ()
+  , dF # ()
+  ]
diff --git a/src/Data/Digit/HEXADECIMAL.hs b/src/Data/Digit/HEXADECIMAL.hs
--- a/src/Data/Digit/HEXADECIMAL.hs
+++ b/src/Data/Digit/HEXADECIMAL.hs
@@ -1,138 +1,112 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 module Data.Digit.HEXADECIMAL(
-  HEXADECIMALNoZero
+  HEXDigit(..)
+, HEXADECIMALNoZero
 , HEXADECIMAL
 , parseHEXADECIMALNoZero
 , parseHEXADECIMAL
+-- * Prisms
+, _HEXDigit0
+, _HEXDigit1
+, _HEXDigit2
+, _HEXDigit3
+, _HEXDigit4
+, _HEXDigit5
+, _HEXDigit6
+, _HEXDigit7
+, _HEXDigit8
+, _HEXDigit9
+, _HEXDigitA
+, _HEXDigitB
+, _HEXDigitC
+, _HEXDigitD
+, _HEXDigitE
+, _HEXDigitF
+-- * Re-exports
+, module Data.Digit.D0
+, module Data.Digit.D1
+, module Data.Digit.D2
+, module Data.Digit.D3
+, module Data.Digit.D4
+, module Data.Digit.D5
+, module Data.Digit.D6
+, module Data.Digit.D7
+, module Data.Digit.D8
+, module Data.Digit.D9
+, module Data.Digit.DA
+, module Data.Digit.DB
+, module Data.Digit.DC
+, module Data.Digit.DD
+, module Data.Digit.DE
+, module Data.Digit.DF
 ) where
 
+import Prelude (Eq, Show, Ord)
+import Control.Lens.TH (makePrisms)
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.D0(D0, parse0)
-import Data.Digit.D1(D1)
-import Data.Digit.D2(D2)
-import Data.Digit.D3(D3)
-import Data.Digit.D4(D4)
-import Data.Digit.D5(D5)
-import Data.Digit.D6(D6)
-import Data.Digit.D7(D7)
-import Data.Digit.D8(D8)
-import Data.Digit.D9(D9)
-import Data.Digit.DA(DA, parseA)
-import Data.Digit.DB(DB, parseB)
-import Data.Digit.DC(DC, parseC)
-import Data.Digit.DD(DD, parseD)
-import Data.Digit.DE(DE, parseE)
-import Data.Digit.DF(DF, parseF)
+import Data.Digit.D0
+import Data.Digit.D1
+import Data.Digit.D2
+import Data.Digit.D3
+import Data.Digit.D4
+import Data.Digit.D5
+import Data.Digit.D6
+import Data.Digit.D7
+import Data.Digit.D8
+import Data.Digit.D9
+import Data.Digit.DA
+import Data.Digit.DB
+import Data.Digit.DC
+import Data.Digit.DD
+import Data.Digit.DE
+import Data.Digit.DF
 import Data.Digit.Decimal(parseDecimalNoZero)
 
--- $setup
--- >>> import Text.Parsec(parse, ParseError, eof)
--- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
--- >>> import Papa
+data HEXDigit
+  = HEXDigit0
+  | HEXDigit1
+  | HEXDigit2
+  | HEXDigit3
+  | HEXDigit4
+  | HEXDigit5
+  | HEXDigit6
+  | HEXDigit7
+  | HEXDigit8
+  | HEXDigit9
+  | HEXDigitA
+  | HEXDigitB
+  | HEXDigitC
+  | HEXDigitD
+  | HEXDigitE
+  | HEXDigitF
+  deriving (Show, Eq, Ord)
 
+makePrisms ''HEXDigit
+
+instance D0 HEXDigit where; d0 = _HEXDigit0
+instance D1 HEXDigit where; d1 = _HEXDigit1
+instance D2 HEXDigit where; d2 = _HEXDigit2
+instance D3 HEXDigit where; d3 = _HEXDigit3
+instance D4 HEXDigit where; d4 = _HEXDigit4
+instance D5 HEXDigit where; d5 = _HEXDigit5
+instance D6 HEXDigit where; d6 = _HEXDigit6
+instance D7 HEXDigit where; d7 = _HEXDigit7
+instance D8 HEXDigit where; d8 = _HEXDigit8
+instance D9 HEXDigit where; d9 = _HEXDigit9
+instance DA HEXDigit where; dA = _HEXDigitA
+instance DB HEXDigit where; dB = _HEXDigitB
+instance DC HEXDigit where; dC = _HEXDigitC
+instance DD HEXDigit where; dD = _HEXDigitD
+instance DE HEXDigit where; dE = _HEXDigitE
+instance DF HEXDigit where; dF = _HEXDigitF
+
 type HEXADECIMALNoZero d =
   (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d, D8 d, D9 d, DA d, DB d, DC d, DD d, DE d, DF d)
 
--- |
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseHEXADECIMALNoZero "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseHEXADECIMALNoZero "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseHEXADECIMALNoZero "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseHEXADECIMALNoZero "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseHEXADECIMALNoZero "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseHEXADECIMALNoZero "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseHEXADECIMALNoZero "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "8" :: Either ParseError Digit
--- Right 8
---
--- >>> parse parseHEXADECIMALNoZero "test" "8xyz" :: Either ParseError Digit
--- Right 8
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "9" :: Either ParseError Digit
--- Right 9
---
--- >>> parse parseHEXADECIMALNoZero "test" "9xyz" :: Either ParseError Digit
--- Right 9
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "A" :: Either ParseError Digit
--- Right A
---
--- >>> parse parseHEXADECIMALNoZero "test" "Axyz" :: Either ParseError Digit
--- Right A
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "B" :: Either ParseError Digit
--- Right B
---
--- >>> parse parseHEXADECIMALNoZero "test" "Bxyz" :: Either ParseError Digit
--- Right B
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "C" :: Either ParseError Digit
--- Right C
---
--- >>> parse parseHEXADECIMALNoZero "test" "Cxyz" :: Either ParseError Digit
--- Right C
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "D" :: Either ParseError Digit
--- Right D
---
--- >>> parse parseHEXADECIMALNoZero "test" "Dxyz" :: Either ParseError Digit
--- Right D
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "E" :: Either ParseError Digit
--- Right E
---
--- >>> parse parseHEXADECIMALNoZero "test" "Exyz" :: Either ParseError Digit
--- Right E
---
--- >>> parse (parseHEXADECIMALNoZero <* eof) "test" "F" :: Either ParseError Digit
--- Right F
---
--- >>> parse parseHEXADECIMALNoZero "test" "Fxyz" :: Either ParseError Digit
--- Right F
---
--- >>> isn't _Right (parse parseHEXADECIMALNoZero "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "123456789ABCDEF") ==> isn't _Right (parse parseHEXADECIMALNoZero "test" [c] :: Either ParseError Digit)
 parseHEXADECIMALNoZero ::
   (HEXADECIMALNoZero d, CharParsing p) =>
   p d
@@ -151,108 +125,6 @@
 type HEXADECIMAL d =
   (D0 d, HEXADECIMALNoZero d)
 
--- |
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "0" :: Either ParseError Digit
--- Right 0
---
--- >>> parse parseHEXADECIMAL "test" "0xyz" :: Either ParseError Digit
--- Right 0
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseHEXADECIMAL "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseHEXADECIMAL "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseHEXADECIMAL "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseHEXADECIMAL "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseHEXADECIMAL "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseHEXADECIMAL "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseHEXADECIMAL "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "8" :: Either ParseError Digit
--- Right 8
---
--- >>> parse parseHEXADECIMAL "test" "8xyz" :: Either ParseError Digit
--- Right 8
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "9" :: Either ParseError Digit
--- Right 9
---
--- >>> parse parseHEXADECIMAL "test" "9xyz" :: Either ParseError Digit
--- Right 9
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "A" :: Either ParseError Digit
--- Right A
---
--- >>> parse parseHEXADECIMAL "test" "Axyz" :: Either ParseError Digit
--- Right A
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "B" :: Either ParseError Digit
--- Right B
---
--- >>> parse parseHEXADECIMAL "test" "Bxyz" :: Either ParseError Digit
--- Right B
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "C" :: Either ParseError Digit
--- Right C
---
--- >>> parse parseHEXADECIMAL "test" "Cxyz" :: Either ParseError Digit
--- Right C
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "D" :: Either ParseError Digit
--- Right D
---
--- >>> parse parseHEXADECIMAL "test" "Dxyz" :: Either ParseError Digit
--- Right D
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "E" :: Either ParseError Digit
--- Right E
---
--- >>> parse parseHEXADECIMAL "test" "Exyz" :: Either ParseError Digit
--- Right E
---
--- >>> parse (parseHEXADECIMAL <* eof) "test" "F" :: Either ParseError Digit
--- Right F
---
--- >>> parse parseHEXADECIMAL "test" "Fxyz" :: Either ParseError Digit
--- Right F
---
--- >>> isn't _Right (parse parseHEXADECIMAL "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "0123456789ABCDEF") ==> isn't _Right (parse parseHEXADECIMAL "test" [c] :: Either ParseError Digit)
 parseHEXADECIMAL ::
   (HEXADECIMAL d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/HeXaDeCiMaL.hs b/src/Data/Digit/HeXaDeCiMaL.hs
--- a/src/Data/Digit/HeXaDeCiMaL.hs
+++ b/src/Data/Digit/HeXaDeCiMaL.hs
@@ -1,186 +1,130 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 module Data.Digit.HeXaDeCiMaL(
-  HeXaDeCiMaLNoZero
+  HeXDigit(..)
+, HeXaDeCiMaLNoZero
 , HeXaDeCiMaL
 , parseHeXaDeCiMaLNoZero
 , parseHeXaDeCiMaL
+-- * Prisms
+, _HeXDigit0
+, _HeXDigit1
+, _HeXDigit2
+, _HeXDigit3
+, _HeXDigit4
+, _HeXDigit5
+, _HeXDigit6
+, _HeXDigit7
+, _HeXDigit8
+, _HeXDigit9
+, _HeXDigita
+, _HeXDigitb
+, _HeXDigitc
+, _HeXDigitd
+, _HeXDigite
+, _HeXDigitf
+, _HeXDigitA
+, _HeXDigitB
+, _HeXDigitC
+, _HeXDigitD
+, _HeXDigitE
+, _HeXDigitF
+-- * Re-exports
+, module Data.Digit.D0
+, module Data.Digit.D1
+, module Data.Digit.D2
+, module Data.Digit.D3
+, module Data.Digit.D4
+, module Data.Digit.D5
+, module Data.Digit.D6
+, module Data.Digit.D7
+, module Data.Digit.D8
+, module Data.Digit.D9
+, module Data.Digit.DAa
+, module Data.Digit.DBb
+, module Data.Digit.DCc
+, module Data.Digit.DDd
+, module Data.Digit.DEe
+, module Data.Digit.DFf
 ) where
 
+import Prelude (Eq, Show, Ord)
+import Control.Lens.TH (makePrisms)
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.D0(D0, parse0)
-import Data.Digit.D1(D1)
-import Data.Digit.D2(D2)
-import Data.Digit.D3(D3)
-import Data.Digit.D4(D4)
-import Data.Digit.D5(D5)
-import Data.Digit.D6(D6)
-import Data.Digit.D7(D7)
-import Data.Digit.D8(D8)
-import Data.Digit.D9(D9)
-import Data.Digit.DA(DA)
-import Data.Digit.DB(DB)
-import Data.Digit.DC(DC)
-import Data.Digit.DD(DD)
-import Data.Digit.DE(DE)
-import Data.Digit.DF(DF)
-import Data.Digit.Da(Da)
-import Data.Digit.Db(Db)
-import Data.Digit.Dc(Dc)
-import Data.Digit.Dd(Dd)
-import Data.Digit.De(De)
-import Data.Digit.Df(Df)
+import Data.Digit.D0
+import Data.Digit.D1
+import Data.Digit.D2
+import Data.Digit.D3
+import Data.Digit.D4
+import Data.Digit.D5
+import Data.Digit.D6
+import Data.Digit.D7
+import Data.Digit.D8
+import Data.Digit.D9
 import Data.Digit.Decimal(parseDecimalNoZero)
-import Data.Digit.DAa(parseAa)
-import Data.Digit.DBb(parseBb)
-import Data.Digit.DCc(parseCc)
-import Data.Digit.DDd(parseDd)
-import Data.Digit.DEe(parseEe)
-import Data.Digit.DFf(parseFf)
+import Data.Digit.DAa
+import Data.Digit.DBb
+import Data.Digit.DCc
+import Data.Digit.DDd
+import Data.Digit.DEe
+import Data.Digit.DFf
 
--- $setup
--- >>> import Text.Parsec(parse, ParseError, eof)
--- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
--- >>> import Papa
+data HeXDigit
+  = HeXDigit0
+  | HeXDigit1
+  | HeXDigit2
+  | HeXDigit3
+  | HeXDigit4
+  | HeXDigit5
+  | HeXDigit6
+  | HeXDigit7
+  | HeXDigit8
+  | HeXDigit9
+  | HeXDigita
+  | HeXDigitb
+  | HeXDigitc
+  | HeXDigitd
+  | HeXDigite
+  | HeXDigitf
+  | HeXDigitA
+  | HeXDigitB
+  | HeXDigitC
+  | HeXDigitD
+  | HeXDigitE
+  | HeXDigitF
+  deriving (Show, Eq, Ord)
 
+makePrisms ''HeXDigit
+
+instance D0 HeXDigit where; d0 = _HeXDigit0
+instance D1 HeXDigit where; d1 = _HeXDigit1
+instance D2 HeXDigit where; d2 = _HeXDigit2
+instance D3 HeXDigit where; d3 = _HeXDigit3
+instance D4 HeXDigit where; d4 = _HeXDigit4
+instance D5 HeXDigit where; d5 = _HeXDigit5
+instance D6 HeXDigit where; d6 = _HeXDigit6
+instance D7 HeXDigit where; d7 = _HeXDigit7
+instance D8 HeXDigit where; d8 = _HeXDigit8
+instance D9 HeXDigit where; d9 = _HeXDigit9
+instance DA HeXDigit where; dA = _HeXDigitA
+instance Da HeXDigit where; da = _HeXDigita
+instance DB HeXDigit where; dB = _HeXDigitB
+instance Db HeXDigit where; db = _HeXDigitb
+instance DC HeXDigit where; dC = _HeXDigitC
+instance Dc HeXDigit where; dc = _HeXDigitc
+instance DD HeXDigit where; dD = _HeXDigitD
+instance Dd HeXDigit where; dd = _HeXDigitd
+instance DE HeXDigit where; dE = _HeXDigitE
+instance De HeXDigit where; de = _HeXDigite
+instance DF HeXDigit where; dF = _HeXDigitF
+instance Df HeXDigit where; df = _HeXDigitf
+
 type HeXaDeCiMaLNoZero d =
   (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d, D8 d, D9 d, DA d, DB d, DC d, DD d, DE d, DF d, Da d, Db d, Dc d, Dd d, De d, De d, Df d)
 
--- |
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "8" :: Either ParseError Digit
--- Right 8
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "8xyz" :: Either ParseError Digit
--- Right 8
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "9" :: Either ParseError Digit
--- Right 9
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "9xyz" :: Either ParseError Digit
--- Right 9
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "a" :: Either ParseError Digit
--- Right a
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "axyz" :: Either ParseError Digit
--- Right a
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "b" :: Either ParseError Digit
--- Right b
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "bxyz" :: Either ParseError Digit
--- Right b
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "c" :: Either ParseError Digit
--- Right c
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "cxyz" :: Either ParseError Digit
--- Right c
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "d" :: Either ParseError Digit
--- Right d
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "dxyz" :: Either ParseError Digit
--- Right d
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "e" :: Either ParseError Digit
--- Right e
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "exyz" :: Either ParseError Digit
--- Right e
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "f" :: Either ParseError Digit
--- Right f
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "fxyz" :: Either ParseError Digit
--- Right f
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "A" :: Either ParseError Digit
--- Right A
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "Axyz" :: Either ParseError Digit
--- Right A
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "B" :: Either ParseError Digit
--- Right B
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "Bxyz" :: Either ParseError Digit
--- Right B
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "C" :: Either ParseError Digit
--- Right C
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "Cxyz" :: Either ParseError Digit
--- Right C
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "D" :: Either ParseError Digit
--- Right D
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "Dxyz" :: Either ParseError Digit
--- Right D
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "E" :: Either ParseError Digit
--- Right E
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "Exyz" :: Either ParseError Digit
--- Right E
---
--- >>> parse (parseHeXaDeCiMaLNoZero <* eof) "test" "F" :: Either ParseError Digit
--- Right F
---
--- >>> parse parseHeXaDeCiMaLNoZero "test" "Fxyz" :: Either ParseError Digit
--- Right F
---
--- >>> isn't _Right (parse parseHeXaDeCiMaLNoZero "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "123456789abcdefABCDEF") ==> isn't _Right (parse parseHeXaDeCiMaLNoZero "test" [c] :: Either ParseError Digit)
 parseHeXaDeCiMaLNoZero ::
   (HeXaDeCiMaLNoZero d, CharParsing p) =>
   p d
@@ -199,144 +143,6 @@
 type HeXaDeCiMaL d =
   (D0 d, HeXaDeCiMaLNoZero d)
 
--- |
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "0" :: Either ParseError Digit
--- Right 0
---
--- >>> parse parseHeXaDeCiMaL "test" "0xyz" :: Either ParseError Digit
--- Right 0
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseHeXaDeCiMaL "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseHeXaDeCiMaL "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseHeXaDeCiMaL "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseHeXaDeCiMaL "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseHeXaDeCiMaL "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseHeXaDeCiMaL "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseHeXaDeCiMaL "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "8" :: Either ParseError Digit
--- Right 8
---
--- >>> parse parseHeXaDeCiMaL "test" "8xyz" :: Either ParseError Digit
--- Right 8
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "9" :: Either ParseError Digit
--- Right 9
---
--- >>> parse parseHeXaDeCiMaL "test" "9xyz" :: Either ParseError Digit
--- Right 9
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "a" :: Either ParseError Digit
--- Right a
---
--- >>> parse parseHeXaDeCiMaL "test" "axyz" :: Either ParseError Digit
--- Right a
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "b" :: Either ParseError Digit
--- Right b
---
--- >>> parse parseHeXaDeCiMaL "test" "bxyz" :: Either ParseError Digit
--- Right b
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "c" :: Either ParseError Digit
--- Right c
---
--- >>> parse parseHeXaDeCiMaL "test" "cxyz" :: Either ParseError Digit
--- Right c
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "d" :: Either ParseError Digit
--- Right d
---
--- >>> parse parseHeXaDeCiMaL "test" "dxyz" :: Either ParseError Digit
--- Right d
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "e" :: Either ParseError Digit
--- Right e
---
--- >>> parse parseHeXaDeCiMaL "test" "exyz" :: Either ParseError Digit
--- Right e
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "f" :: Either ParseError Digit
--- Right f
---
--- >>> parse parseHeXaDeCiMaL "test" "fxyz" :: Either ParseError Digit
--- Right f
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "A" :: Either ParseError Digit
--- Right A
---
--- >>> parse parseHeXaDeCiMaL "test" "Axyz" :: Either ParseError Digit
--- Right A
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "B" :: Either ParseError Digit
--- Right B
---
--- >>> parse parseHeXaDeCiMaL "test" "Bxyz" :: Either ParseError Digit
--- Right B
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "C" :: Either ParseError Digit
--- Right C
---
--- >>> parse parseHeXaDeCiMaL "test" "Cxyz" :: Either ParseError Digit
--- Right C
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "D" :: Either ParseError Digit
--- Right D
---
--- >>> parse parseHeXaDeCiMaL "test" "Dxyz" :: Either ParseError Digit
--- Right D
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "E" :: Either ParseError Digit
--- Right E
---
--- >>> parse parseHeXaDeCiMaL "test" "Exyz" :: Either ParseError Digit
--- Right E
---
--- >>> parse (parseHeXaDeCiMaL <* eof) "test" "F" :: Either ParseError Digit
--- Right F
---
--- >>> parse parseHeXaDeCiMaL "test" "Fxyz" :: Either ParseError Digit
--- Right F
---
--- >>> isn't _Right (parse parseHeXaDeCiMaL "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "0123456789abcdefABCDEF") ==> isn't _Right (parse parseHeXaDeCiMaL "test" [c] :: Either ParseError Digit)
 parseHeXaDeCiMaL ::
   (HeXaDeCiMaL d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/Hexadecimal.hs b/src/Data/Digit/Hexadecimal.hs
--- a/src/Data/Digit/Hexadecimal.hs
+++ b/src/Data/Digit/Hexadecimal.hs
@@ -1,138 +1,112 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 module Data.Digit.Hexadecimal(
-  HexadecimalNoZero
+  HexDigit(..)
+, HexadecimalNoZero
 , Hexadecimal
 , parseHexadecimalNoZero
 , parseHexadecimal
+-- * Prisms
+, _HexDigit0
+, _HexDigit1
+, _HexDigit2
+, _HexDigit3
+, _HexDigit4
+, _HexDigit5
+, _HexDigit6
+, _HexDigit7
+, _HexDigit8
+, _HexDigit9
+, _HexDigita
+, _HexDigitb
+, _HexDigitc
+, _HexDigitd
+, _HexDigite
+, _HexDigitf
+-- * Re-exports
+, module Data.Digit.D0
+, module Data.Digit.D1
+, module Data.Digit.D2
+, module Data.Digit.D3
+, module Data.Digit.D4
+, module Data.Digit.D5
+, module Data.Digit.D6
+, module Data.Digit.D7
+, module Data.Digit.D8
+, module Data.Digit.D9
+, module Data.Digit.Da
+, module Data.Digit.Db
+, module Data.Digit.Dc
+, module Data.Digit.Dd
+, module Data.Digit.De
+, module Data.Digit.Df
 ) where
 
+import Prelude (Eq, Show, Ord)
+import Control.Lens.TH (makePrisms)
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.D0(D0, parse0)
-import Data.Digit.D1(D1)
-import Data.Digit.D2(D2)
-import Data.Digit.D3(D3)
-import Data.Digit.D4(D4)
-import Data.Digit.D5(D5)
-import Data.Digit.D6(D6)
-import Data.Digit.D7(D7)
-import Data.Digit.D8(D8)
-import Data.Digit.D9(D9)
-import Data.Digit.Da(Da, parsea)
-import Data.Digit.Db(Db, parseb)
-import Data.Digit.Dc(Dc, parsec)
-import Data.Digit.Dd(Dd, parsed)
-import Data.Digit.De(De, parsee)
-import Data.Digit.Df(Df, parsef)
+import Data.Digit.D0
+import Data.Digit.D1
+import Data.Digit.D2
+import Data.Digit.D3
+import Data.Digit.D4
+import Data.Digit.D5
+import Data.Digit.D6
+import Data.Digit.D7
+import Data.Digit.D8
+import Data.Digit.D9
+import Data.Digit.Da
+import Data.Digit.Db
+import Data.Digit.Dc
+import Data.Digit.Dd
+import Data.Digit.De
+import Data.Digit.Df
 import Data.Digit.Decimal(parseDecimalNoZero)
 
--- $setup
--- >>> import Text.Parsec(parse, ParseError, eof)
--- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
--- >>> import Papa
+data HexDigit
+  = HexDigit0
+  | HexDigit1
+  | HexDigit2
+  | HexDigit3
+  | HexDigit4
+  | HexDigit5
+  | HexDigit6
+  | HexDigit7
+  | HexDigit8
+  | HexDigit9
+  | HexDigita
+  | HexDigitb
+  | HexDigitc
+  | HexDigitd
+  | HexDigite
+  | HexDigitf
+  deriving (Show, Eq, Ord)
 
+makePrisms ''HexDigit
+
+instance D0 HexDigit where; d0 = _HexDigit0
+instance D1 HexDigit where; d1 = _HexDigit1
+instance D2 HexDigit where; d2 = _HexDigit2
+instance D3 HexDigit where; d3 = _HexDigit3
+instance D4 HexDigit where; d4 = _HexDigit4
+instance D5 HexDigit where; d5 = _HexDigit5
+instance D6 HexDigit where; d6 = _HexDigit6
+instance D7 HexDigit where; d7 = _HexDigit7
+instance D8 HexDigit where; d8 = _HexDigit8
+instance D9 HexDigit where; d9 = _HexDigit9
+instance Da HexDigit where; da = _HexDigita
+instance Db HexDigit where; db = _HexDigitb
+instance Dc HexDigit where; dc = _HexDigitc
+instance Dd HexDigit where; dd = _HexDigitd
+instance De HexDigit where; de = _HexDigite
+instance Df HexDigit where; df = _HexDigitf
+
 type HexadecimalNoZero d =
   (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d, D8 d, D9 d, Da d, Db d, Dc d, Dd d, De d, De d, Df d)
 
--- |
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseHexadecimalNoZero "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseHexadecimalNoZero "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseHexadecimalNoZero "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseHexadecimalNoZero "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseHexadecimalNoZero "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseHexadecimalNoZero "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseHexadecimalNoZero "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "8" :: Either ParseError Digit
--- Right 8
---
--- >>> parse parseHexadecimalNoZero "test" "8xyz" :: Either ParseError Digit
--- Right 8
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "9" :: Either ParseError Digit
--- Right 9
---
--- >>> parse parseHexadecimalNoZero "test" "9xyz" :: Either ParseError Digit
--- Right 9
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "a" :: Either ParseError Digit
--- Right a
---
--- >>> parse parseHexadecimalNoZero "test" "axyz" :: Either ParseError Digit
--- Right a
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "b" :: Either ParseError Digit
--- Right b
---
--- >>> parse parseHexadecimalNoZero "test" "bxyz" :: Either ParseError Digit
--- Right b
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "c" :: Either ParseError Digit
--- Right c
---
--- >>> parse parseHexadecimalNoZero "test" "cxyz" :: Either ParseError Digit
--- Right c
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "d" :: Either ParseError Digit
--- Right d
---
--- >>> parse parseHexadecimalNoZero "test" "dxyz" :: Either ParseError Digit
--- Right d
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "e" :: Either ParseError Digit
--- Right e
---
--- >>> parse parseHexadecimalNoZero "test" "exyz" :: Either ParseError Digit
--- Right e
---
--- >>> parse (parseHexadecimalNoZero <* eof) "test" "f" :: Either ParseError Digit
--- Right f
---
--- >>> parse parseHexadecimalNoZero "test" "fxyz" :: Either ParseError Digit
--- Right f
---
--- >>> isn't _Right (parse parseHexadecimalNoZero "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "123456789abcdef") ==> isn't _Right (parse parseHexadecimalNoZero "test" [c] :: Either ParseError Digit)
 parseHexadecimalNoZero ::
   (HexadecimalNoZero d, CharParsing p) =>
   p d
@@ -151,108 +125,6 @@
 type Hexadecimal d =
   (D0 d, HexadecimalNoZero d)
 
--- |
---
--- >>> parse (parseHexadecimal <* eof) "test" "0" :: Either ParseError Digit
--- Right 0
---
--- >>> parse parseHexadecimal "test" "0xyz" :: Either ParseError Digit
--- Right 0
---
--- >>> parse (parseHexadecimal <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseHexadecimal "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseHexadecimal <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseHexadecimal "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseHexadecimal <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseHexadecimal "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseHexadecimal <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseHexadecimal "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseHexadecimal <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseHexadecimal "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseHexadecimal <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseHexadecimal "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseHexadecimal <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseHexadecimal "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> parse (parseHexadecimal <* eof) "test" "8" :: Either ParseError Digit
--- Right 8
---
--- >>> parse parseHexadecimal "test" "8xyz" :: Either ParseError Digit
--- Right 8
---
--- >>> parse (parseHexadecimal <* eof) "test" "9" :: Either ParseError Digit
--- Right 9
---
--- >>> parse parseHexadecimal "test" "9xyz" :: Either ParseError Digit
--- Right 9
---
--- >>> parse (parseHexadecimal <* eof) "test" "a" :: Either ParseError Digit
--- Right a
---
--- >>> parse parseHexadecimal "test" "axyz" :: Either ParseError Digit
--- Right a
---
--- >>> parse (parseHexadecimal <* eof) "test" "b" :: Either ParseError Digit
--- Right b
---
--- >>> parse parseHexadecimal "test" "bxyz" :: Either ParseError Digit
--- Right b
---
--- >>> parse (parseHexadecimal <* eof) "test" "c" :: Either ParseError Digit
--- Right c
---
--- >>> parse parseHexadecimal "test" "cxyz" :: Either ParseError Digit
--- Right c
---
--- >>> parse (parseHexadecimal <* eof) "test" "d" :: Either ParseError Digit
--- Right d
---
--- >>> parse parseHexadecimal "test" "dxyz" :: Either ParseError Digit
--- Right d
---
--- >>> parse (parseHexadecimal <* eof) "test" "e" :: Either ParseError Digit
--- Right e
---
--- >>> parse parseHexadecimal "test" "exyz" :: Either ParseError Digit
--- Right e
---
--- >>> parse (parseHexadecimal <* eof) "test" "f" :: Either ParseError Digit
--- Right f
---
--- >>> parse parseHexadecimal "test" "fxyz" :: Either ParseError Digit
--- Right f
---
--- >>> isn't _Right (parse parseHexadecimal "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "0123456789abcdef") ==> isn't _Right (parse parseHexadecimal "test" [c] :: Either ParseError Digit)
 parseHexadecimal ::
   (Hexadecimal d, CharParsing p) =>
   p d
diff --git a/src/Data/Digit/Integral.hs b/src/Data/Digit/Integral.hs
--- a/src/Data/Digit/Integral.hs
+++ b/src/Data/Digit/Integral.hs
@@ -1,60 +1,58 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 
 module Data.Digit.Integral(
+-- * Binary
   integralBinaryNoZero
 , integralBinary
+, integralBinDigits
+, binDigitsIntegral
+-- * Octal
 , integralOctalNoZero
 , integralOctal
+, integralOctDigits
+, octDigitsIntegral
+-- * Decimal
 , integralDecimal
 , integralDecimalNoZero
+, integralDecDigits
+, decDigitsIntegral
+-- * Hexadecimal
 , integralHexadecimalNoZero
 , integralHexadecimal
+, integralHexDigits
+, hexDigitsIntegral
+-- * HEXADECIMAL
 , integralHEXADECIMALNoZero
 , integralHEXADECIMAL
+, integralHEXDigits
+, _HEXDigitsIntegral
+-- * HeXaDeCiMaL
+, integralHeXaDeCiMaLNoZero
+, integralHeXaDeCiMaL
+, _HeXDigitsIntegral
 ) where
 
+import Prelude (error)
 import Control.Lens.Extras(is)
-import Data.Digit.Binary as D
-import Data.Digit.Decimal as D
-import Data.Digit.Octal as D
-import Data.Digit.Hexadecimal as D
-import Data.Digit.HEXADECIMAL as D
-import Data.Digit.D0 as D
-import Data.Digit.D1 as D
-import Data.Digit.D2 as D
-import Data.Digit.D3 as D
-import Data.Digit.D4 as D
-import Data.Digit.D5 as D
-import Data.Digit.D6 as D
-import Data.Digit.D7 as D
-import Data.Digit.D8 as D
-import Data.Digit.D9 as D
-import Data.Digit.Da as D
-import Data.Digit.DA as D
-import Data.Digit.Db as D
-import Data.Digit.DB as D
-import Data.Digit.Dc as D
-import Data.Digit.DC as D
-import Data.Digit.Dd as D
-import Data.Digit.DD as D
-import Data.Digit.De as D
-import Data.Digit.DE as D
-import Data.Digit.Df as D
-import Data.Digit.DF as D
+import Data.Digit.Binary
+import Data.Digit.Decimal
+import Data.Digit.Octal
+import Data.Digit.Hexadecimal
+import Data.Digit.HEXADECIMAL
+import Data.Digit.HeXaDeCiMaL
+import qualified Data.List.NonEmpty as NonEmpty
 import Papa
 
 -- $setup
--- >>> import Data.Digit.Digit
+-- >>> import Data.Digit
 
 -- |
 --
 -- >>> 1 ^? integralBinaryNoZero
--- Just ()
+-- Just BinDigit1
 --
--- >>> integralBinaryNoZero # Digit1 :: Integer
+-- >>> integralBinaryNoZero # BinDigit1 :: Integer
 -- 1
---
--- prop> \c -> c /= 1 ==> (c ^? integralBinaryNoZero == Nothing)
 integralBinaryNoZero ::
   (Integral a, BinaryNoZero d) =>
   Prism'
@@ -65,19 +63,11 @@
   
 -- |
 --
--- >>> 0 ^? integralBinary :: Maybe Digit
--- Just 0
---
--- >>> 1 ^? integralBinary :: Maybe Digit
--- Just 1
+-- >>> 0 ^? integralBinary :: Maybe BinDigit
+-- Just BinDigit0
 --
--- >>> integralBinary # Digit0 :: Integer
+-- >>> integralBinary # BinDigit0 :: Integer
 -- 0
---
--- >>> integralBinary # Digit1 :: Integer
--- 1
---
--- prop> \c -> (c `notElem` [0, 1]) ==> (c ^? integralBinary == Nothing)
 integralBinary ::
   (Integral a, Binary d) =>
   Prism'
@@ -85,52 +75,55 @@
     d
 integralBinary =
   associatePrism (0, d0) [(1, d1)]
-  
+
 -- |
---
--- >>> 1 ^? integralOctalNoZero :: Maybe Digit
--- Just 1
---
--- >>> 2 ^? integralOctalNoZero :: Maybe Digit
--- Just 2
---
--- >>> 3 ^? integralOctalNoZero :: Maybe Digit
--- Just 3
---
--- >>> 4 ^? integralOctalNoZero :: Maybe Digit
--- Just 4
---
--- >>> 5 ^? integralOctalNoZero :: Maybe Digit
--- Just 5
---
--- >>> 6 ^? integralOctalNoZero :: Maybe Digit
--- Just 6
+-- >>> integralBinDigits (4 :: Int)
+-- Right (BinDigit1 :| [BinDigit0, BinDigit0])
 --
--- >>> 7 ^? integralOctalNoZero :: Maybe Digit
--- Just 7
+-- >>> integralBinDigits (0 :: Int)
+-- Right (BinDigit0 :| [])
 --
--- >>> integralOctalNoZero # Digit1 :: Integer
--- 1
+-- >>> integralBinDigits (-1 :: Int)
+-- Left (BinDigit0 :| [])
 --
--- >>> integralOctalNoZero # Digit2 :: Integer
--- 2
+-- >>> integralBinDigits (-4 :: Int)
+-- Left (BinDigit1 :| [BinDigit1])
+integralBinDigits :: Integral a => a -> Either (NonEmpty BinDigit) (NonEmpty BinDigit)
+integralBinDigits n =
+  if n >= 0
+  then Right . NonEmpty.fromList $ go n []
+  else Left . NonEmpty.fromList $ go (-n - 1) []
+  where
+    go k =
+      let
+        (q, r) = quotRem k 2
+      in
+        (if q == 0 then id else go q) . ((r ^?! integralBinary) :)
+
+-- |
+-- >>> binDigitsIntegral (Right (BinDigit1 :| [BinDigit0, BinDigit0])) :: Int
+-- 4
 --
--- >>> integralOctalNoZero # Digit3 :: Integer
--- 3
+-- >>> binDigitsIntegral (Right (BinDigit0 :| [])) :: Int
+-- 0
 --
--- >>> integralOctalNoZero # Digit4 :: Integer
--- 4
+-- >>> binDigitsIntegral (Left (BinDigit0 :| [])) :: Int
+-- -1
 --
--- >>> integralOctalNoZero # Digit5 :: Integer
--- 5
+-- >>> binDigitsIntegral (Left (BinDigit1 :| [BinDigit1])) :: Int
+-- -4
+binDigitsIntegral :: Integral a => Either (NonEmpty BinDigit) (NonEmpty BinDigit) -> a
+binDigitsIntegral = either (\n -> -(go n) - 1) go
+  where
+    go = foldl' (\b a -> (integralBinary # a) + 2 * b) 0
+
+-- |
 --
--- >>> integralOctalNoZero # Digit6 :: Integer
--- 6
+-- >>> 7 ^? integralOctalNoZero :: Maybe OctDigit
+-- Just OctDigit7
 --
--- >>> integralOctalNoZero # Digit7 :: Integer
+-- >>> integralOctalNoZero # OctDigit7 :: Integer
 -- 7
---
--- prop> \c -> (c `notElem` [1..7]) ==> (c ^? integralOctalNoZero == Nothing)
 integralOctalNoZero ::
   (Integral a, OctalNoZero d) =>
   Prism'
@@ -141,55 +134,11 @@
 
 -- |
 --
--- >>> 0 ^? integralOctal :: Maybe Digit
--- Just 0
---
--- >>> 1 ^? integralOctal :: Maybe Digit
--- Just 1
---
--- >>> 2 ^? integralOctal :: Maybe Digit
--- Just 2
---
--- >>> 3 ^? integralOctal :: Maybe Digit
--- Just 3
---
--- >>> 4 ^? integralOctal :: Maybe Digit
--- Just 4
---
--- >>> 5 ^? integralOctal :: Maybe Digit
--- Just 5
---
--- >>> 6 ^? integralOctal :: Maybe Digit
--- Just 6
---
--- >>> 7 ^? integralOctal :: Maybe Digit
--- Just 7
---
--- >>> integralOctal # Digit0 :: Integer
--- 0
---
--- >>> integralOctal # Digit1 :: Integer
--- 1
---
--- >>> integralOctal # Digit2 :: Integer
--- 2
---
--- >>> integralOctal # Digit3 :: Integer
--- 3
---
--- >>> integralOctal # Digit4 :: Integer
--- 4
---
--- >>> integralOctal # Digit5 :: Integer
--- 5
---
--- >>> integralOctal # Digit6 :: Integer
--- 6
+-- >>> 7 ^? integralOctal :: Maybe OctDigit
+-- Just OctDigit7
 --
--- >>> integralOctal # Digit7 :: Integer
+-- >>> integralOctal # OctDigit7 :: Integer
 -- 7
---
--- prop> \c -> (c `notElem` [0..7]) ==> (c ^? integralOctal == Nothing)
 integralOctal ::
   (Integral a, Octal d) =>
   Prism'
@@ -197,64 +146,54 @@
     d
 integralOctal =
   associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7)]
-  
+
 -- |
---
--- >>> 1 ^? integralDecimalNoZero :: Maybe Digit
--- Just 1
---
--- >>> 2 ^? integralDecimalNoZero :: Maybe Digit
--- Just 2
---
--- >>> 3 ^? integralDecimalNoZero :: Maybe Digit
--- Just 3
---
--- >>> 4 ^? integralDecimalNoZero :: Maybe Digit
--- Just 4
---
--- >>> 5 ^? integralDecimalNoZero :: Maybe Digit
--- Just 5
---
--- >>> 6 ^? integralDecimalNoZero :: Maybe Digit
--- Just 6
---
--- >>> 7 ^? integralDecimalNoZero :: Maybe Digit
--- Just 7
---
--- >>> 8 ^? integralDecimalNoZero :: Maybe Digit
--- Just 8
---
--- >>> 9 ^? integralDecimalNoZero :: Maybe Digit
--- Just 9
---
--- >>> integralDecimalNoZero # Digit1 :: Integer
--- 1
---
--- >>> integralDecimalNoZero # Digit2 :: Integer
--- 2
+-- >>> integralOctDigits (64 :: Int)
+-- Right (OctDigit1 :| [OctDigit0, OctDigit0])
 --
--- >>> integralDecimalNoZero # Digit3 :: Integer
--- 3
+-- >>> integralOctDigits (0 :: Int)
+-- Right (OctDigit0 :| [])
 --
--- >>> integralDecimalNoZero # Digit4 :: Integer
--- 4
+-- >>> integralOctDigits (-1 :: Int)
+-- Left (OctDigit0 :| [])
 --
--- >>> integralDecimalNoZero # Digit5 :: Integer
--- 5
+-- >>> integralOctDigits (-64 :: Int)
+-- Left (OctDigit7 :| [OctDigit7])
+integralOctDigits :: Integral a => a -> Either (NonEmpty OctDigit) (NonEmpty OctDigit)
+integralOctDigits n =
+  if n >= 0
+  then Right . NonEmpty.fromList $ go n []
+  else Left . NonEmpty.fromList $ go (-n - 1) []
+  where
+    go k =
+      let
+        (q, r) = quotRem k 8
+      in
+        (if q == 0 then id else go q) . ((r ^?! integralOctal) :)
+
+-- |
+-- >>> octDigitsIntegral (Right (OctDigit1 :| [OctDigit0, OctDigit0])) :: Int
+-- 64
 --
--- >>> integralDecimalNoZero # Digit6 :: Integer
--- 6
+-- >>> octDigitsIntegral (Right (OctDigit0 :| [])) :: Int
+-- 0
 --
--- >>> integralDecimalNoZero # Digit7 :: Integer
--- 7
+-- >>> octDigitsIntegral (Left (OctDigit0 :| [])) :: Int
+-- -1
 --
--- >>> integralDecimalNoZero # Digit8 :: Integer
--- 8
+-- >>> octDigitsIntegral (Left (OctDigit7 :| [OctDigit7])) :: Int
+-- -64
+octDigitsIntegral :: Integral a => Either (NonEmpty OctDigit) (NonEmpty OctDigit) -> a
+octDigitsIntegral = either (\n -> -(go n) - 1) go
+  where
+    go = foldl' (\b a -> (integralOctal # a) + 8 * b) 0
+
+-- |
+-- >>> 9 ^? integralDecimalNoZero :: Maybe DecDigit
+-- Just DecDigit9
 --
--- >>> integralDecimalNoZero # Digit9 :: Integer
+-- >>> integralDecimalNoZero # DecDigit9 :: Integer
 -- 9
---
--- prop> \c -> (c `notElem` [1..9]) ==> (c ^? integralDecimalNoZero == Nothing)
 integralDecimalNoZero ::
   (Integral a, DecimalNoZero d) =>
   Prism'
@@ -264,68 +203,11 @@
   associatePrism (1, d1) [(2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9)]
   
 -- |
---
--- >>> 0 ^? integralDecimal :: Maybe Digit
--- Just 0
---
--- >>> 1 ^? integralDecimal :: Maybe Digit
--- Just 1
---
--- >>> 2 ^? integralDecimal :: Maybe Digit
--- Just 2
---
--- >>> 3 ^? integralDecimal :: Maybe Digit
--- Just 3
---
--- >>> 4 ^? integralDecimal :: Maybe Digit
--- Just 4
---
--- >>> 5 ^? integralDecimal :: Maybe Digit
--- Just 5
---
--- >>> 6 ^? integralDecimal :: Maybe Digit
--- Just 6
---
--- >>> 7 ^? integralDecimal :: Maybe Digit
--- Just 7
---
--- >>> 8 ^? integralDecimal :: Maybe Digit
--- Just 8
---
--- >>> 9 ^? integralDecimal :: Maybe Digit
--- Just 9
---
--- >>> integralDecimal # Digit0 :: Integer
--- 0
---
--- >>> integralDecimal # Digit1 :: Integer
--- 1
---
--- >>> integralDecimal # Digit2 :: Integer
--- 2
---
--- >>> integralDecimal # Digit3 :: Integer
--- 3
---
--- >>> integralDecimal # Digit4 :: Integer
--- 4
---
--- >>> integralDecimal # Digit5 :: Integer
--- 5
---
--- >>> integralDecimal # Digit6 :: Integer
--- 6
---
--- >>> integralDecimal # Digit7 :: Integer
--- 7
---
--- >>> integralDecimal # Digit8 :: Integer
--- 8
+-- >>> 9 ^? integralDecimal :: Maybe DecDigit
+-- Just DecDigit9
 --
--- >>> integralDecimal # Digit9 :: Integer
+-- >>> integralDecimal # DecDigit9 :: Integer
 -- 9
---
--- prop> \c -> (c `notElem` [0..9]) ==> (c ^? integralDecimal == Nothing)
 integralDecimal ::
   (Integral a, Decimal d) =>
   Prism'
@@ -333,100 +215,55 @@
     d
 integralDecimal =
   associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9)]
-  
+
 -- |
---
--- >>> 1 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just 1
---
--- >>> 2 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just 2
---
--- >>> 3 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just 3
---
--- >>> 4 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just 4
---
--- >>> 5 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just 5
---
--- >>> 6 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just 6
---
--- >>> 7 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just 7
---
--- >>> 8 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just 8
---
--- >>> 9 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just 9
---
--- >>> 10 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just a
---
--- >>> 11 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just b
---
--- >>> 12 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just c
---
--- >>> 13 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just d
---
--- >>> 14 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just e
---
--- >>> 15 ^? integralHexadecimalNoZero :: Maybe Digit
--- Just f
---
--- >>> integralHexadecimalNoZero # Digit1 :: Integer
--- 1
---
--- >>> integralHexadecimalNoZero # Digit2 :: Integer
--- 2
---
--- >>> integralHexadecimalNoZero # Digit3 :: Integer
--- 3
---
--- >>> integralHexadecimalNoZero # Digit4 :: Integer
--- 4
---
--- >>> integralHexadecimalNoZero # Digit5 :: Integer
--- 5
---
--- >>> integralHexadecimalNoZero # Digit6 :: Integer
--- 6
---
--- >>> integralHexadecimalNoZero # Digit7 :: Integer
--- 7
+-- >>> integralDecDigits (100 :: Int)
+-- Right (DecDigit1 :| [DecDigit0, DecDigit0])
 --
--- >>> integralHexadecimalNoZero # Digit8 :: Integer
--- 8
+-- >>> integralDecDigits (0 :: Int)
+-- Right (DecDigit0 :| [])
 --
--- >>> integralHexadecimalNoZero # Digit9 :: Integer
--- 9
+-- >>> integralDecDigits (-1 :: Int)
+-- Left (DecDigit0 :| [])
 --
--- >>> integralHexadecimalNoZero # Digita :: Integer
--- 10
+-- >>> integralDecDigits (-100 :: Int)
+-- Left (DecDigit9 :| [DecDigit9])
+integralDecDigits :: Integral a => a -> Either (NonEmpty DecDigit) (NonEmpty DecDigit)
+integralDecDigits n =
+  if n >= 0
+  then Right . NonEmpty.fromList $ go n []
+  else Left . NonEmpty.fromList $ go (-n - 1) []
+  where
+    go k =
+      let
+        (q, r) = quotRem k 10
+      in
+        (if q == 0 then id else go q) . ((r ^?! integralDecimal) :)
+
+-- |
+-- >>> decDigitsIntegral (Right (DecDigit1 :| [DecDigit0, DecDigit0])) :: Int
+-- 100
 --
--- >>> integralHexadecimalNoZero # Digitb :: Integer
--- 11
+-- >>> decDigitsIntegral (Right (DecDigit0 :| [])) :: Int
+-- 0
 --
--- >>> integralHexadecimalNoZero # Digitc :: Integer
--- 12
+-- >>> decDigitsIntegral (Left (DecDigit0 :| [])) :: Int
+-- -1
 --
--- >>> integralHexadecimalNoZero # Digitd :: Integer
--- 13
+-- >>> decDigitsIntegral (Left (DecDigit9 :| [DecDigit9])) :: Int
+-- -100
+decDigitsIntegral :: Integral a => Either (NonEmpty DecDigit) (NonEmpty DecDigit) -> a
+decDigitsIntegral = either (\n -> -(go n) - 1) go
+  where
+    go = foldl' (\b a -> (integralDecimal # a) + 10 * b) 0
+
+-- |
 --
--- >>> integralHexadecimalNoZero # Digite :: Integer
--- 14
+-- >>> 15 ^? integralHexadecimalNoZero :: Maybe HexDigit
+-- Just HexDigitf
 --
--- >>> integralHexadecimalNoZero # Digitf :: Integer
+-- >>> integralHexadecimalNoZero # HexDigitf :: Integer
 -- 15
---
--- prop> \c -> (c `notElem` [1..15]) ==> (c ^? integralHexadecimalNoZero == Nothing)
 integralHexadecimalNoZero ::
   (Integral a, HexadecimalNoZero d) =>
   Prism'
@@ -437,103 +274,11 @@
   
 -- |
 --
--- >>> 0 ^? integralHexadecimal :: Maybe Digit
--- Just 0
---
--- >>> 1 ^? integralHexadecimal :: Maybe Digit
--- Just 1
---
--- >>> 2 ^? integralHexadecimal :: Maybe Digit
--- Just 2
---
--- >>> 3 ^? integralHexadecimal :: Maybe Digit
--- Just 3
---
--- >>> 4 ^? integralHexadecimal :: Maybe Digit
--- Just 4
---
--- >>> 5 ^? integralHexadecimal :: Maybe Digit
--- Just 5
---
--- >>> 6 ^? integralHexadecimal :: Maybe Digit
--- Just 6
---
--- >>> 7 ^? integralHexadecimal :: Maybe Digit
--- Just 7
---
--- >>> 8 ^? integralHexadecimal :: Maybe Digit
--- Just 8
---
--- >>> 9 ^? integralHexadecimal :: Maybe Digit
--- Just 9
---
--- >>> 10 ^? integralHexadecimal :: Maybe Digit
--- Just a
---
--- >>> 11 ^? integralHexadecimal :: Maybe Digit
--- Just b
---
--- >>> 12 ^? integralHexadecimal :: Maybe Digit
--- Just c
---
--- >>> 13 ^? integralHexadecimal :: Maybe Digit
--- Just d
---
--- >>> 14 ^? integralHexadecimal :: Maybe Digit
--- Just e
---
--- >>> 15 ^? integralHexadecimal :: Maybe Digit
--- Just f
---
--- >>> integralHexadecimal # Digit0 :: Integer
--- 0
---
--- >>> integralHexadecimal # Digit1 :: Integer
--- 1
---
--- >>> integralHexadecimal # Digit2 :: Integer
--- 2
---
--- >>> integralHexadecimal # Digit3 :: Integer
--- 3
---
--- >>> integralHexadecimal # Digit4 :: Integer
--- 4
---
--- >>> integralHexadecimal # Digit5 :: Integer
--- 5
---
--- >>> integralHexadecimal # Digit6 :: Integer
--- 6
---
--- >>> integralHexadecimal # Digit7 :: Integer
--- 7
---
--- >>> integralHexadecimal # Digit8 :: Integer
--- 8
---
--- >>> integralHexadecimal # Digit9 :: Integer
--- 9
---
--- >>> integralHexadecimal # Digita :: Integer
--- 10
---
--- >>> integralHexadecimal # Digitb :: Integer
--- 11
---
--- >>> integralHexadecimal # Digitc :: Integer
--- 12
---
--- >>> integralHexadecimal # Digitd :: Integer
--- 13
---
--- >>> integralHexadecimal # Digite :: Integer
--- 14
+-- >>> 15 ^? integralHexadecimal :: Maybe HexDigit
+-- Just HexDigitf
 --
--- >>> integralHexadecimal # Digitf :: Integer
+-- >>> integralHexadecimal # HexDigitf :: Integer
 -- 15
---
--- prop> \c -> (c `notElem` [0..15]) ==> (c ^? integralHexadecimal == Nothing)
 integralHexadecimal ::
   (Integral a, Hexadecimal d) =>
   Prism'
@@ -543,98 +288,53 @@
   associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, da), (11, db), (12, dc), (13, dd), (14, de), (15, df)]
 
 -- |
---
--- >>> 1 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just 1
---
--- >>> 2 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just 2
---
--- >>> 3 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just 3
---
--- >>> 4 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just 4
---
--- >>> 5 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just 5
---
--- >>> 6 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just 6
---
--- >>> 7 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just 7
---
--- >>> 8 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just 8
---
--- >>> 9 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just 9
---
--- >>> 10 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just A
---
--- >>> 11 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just B
---
--- >>> 12 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just C
---
--- >>> 13 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just D
---
--- >>> 14 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just E
---
--- >>> 15 ^? integralHEXADECIMALNoZero :: Maybe Digit
--- Just F
---
--- >>> integralHEXADECIMALNoZero # Digit1 :: Integer
--- 1
---
--- >>> integralHEXADECIMALNoZero # Digit2 :: Integer
--- 2
---
--- >>> integralHEXADECIMALNoZero # Digit3 :: Integer
--- 3
---
--- >>> integralHEXADECIMALNoZero # Digit4 :: Integer
--- 4
---
--- >>> integralHEXADECIMALNoZero # Digit5 :: Integer
--- 5
---
--- >>> integralHEXADECIMALNoZero # Digit6 :: Integer
--- 6
---
--- >>> integralHEXADECIMALNoZero # Digit7 :: Integer
--- 7
+-- >>> integralHexDigits (256 :: Int)
+-- Right (HexDigit1 :| [HexDigit0, HexDigit0])
 --
--- >>> integralHEXADECIMALNoZero # Digit8 :: Integer
--- 8
+-- >>> integralHexDigits (0 :: Int)
+-- Right (HexDigit0 :| [])
 --
--- >>> integralHEXADECIMALNoZero # Digit9 :: Integer
--- 9
+-- >>> integralHexDigits (-1 :: Int)
+-- Left (HexDigit0 :| [])
 --
--- >>> integralHEXADECIMALNoZero # DigitA :: Integer
--- 10
+-- >>> integralHexDigits (-256 :: Int)
+-- Left (HexDigitf :| [HexDigitf])
+integralHexDigits :: Integral a => a -> Either (NonEmpty HexDigit) (NonEmpty HexDigit)
+integralHexDigits n =
+  if n >= 0
+  then Right . NonEmpty.fromList $ go n []
+  else Left . NonEmpty.fromList $ go (-n - 1) []
+  where
+    go k =
+      let
+        (q, r) = quotRem k 16
+      in
+        (if q == 0 then id else go q) . ((r ^?! integralHexadecimal) :)
+
+-- |
+-- >>> hexDigitsIntegral (Right (HexDigit1 :| [HexDigit0, HexDigit0])) :: Int
+-- 256
 --
--- >>> integralHEXADECIMALNoZero # DigitB :: Integer
--- 11
+-- >>> hexDigitsIntegral (Right (HexDigit0 :| [])) :: Int
+-- 0
 --
--- >>> integralHEXADECIMALNoZero # DigitC :: Integer
--- 12
+-- >>> hexDigitsIntegral (Left (HexDigit0 :| [])) :: Int
+-- -1
 --
--- >>> integralHEXADECIMALNoZero # DigitD :: Integer
--- 13
+-- >>> hexDigitsIntegral (Left (HexDigitf :| [HexDigitf])) :: Int
+-- -256
+hexDigitsIntegral :: Integral a => Either (NonEmpty HexDigit) (NonEmpty HexDigit) -> a
+hexDigitsIntegral = either (\n -> -(go n) - 1) go
+  where
+    go = foldl' (\b a -> (integralHexadecimal # a) + 16 * b) 0
+
+-- |
 --
--- >>> integralHEXADECIMALNoZero # DigitE :: Integer
--- 14
+-- >>> 15 ^? integralHEXADECIMALNoZero :: Maybe HEXDigit
+-- Just HEXDigitF
 --
--- >>> integralHEXADECIMALNoZero # DigitF :: Integer
+-- >>> integralHEXADECIMALNoZero # HEXDigitF :: Integer
 -- 15
---
--- prop> \c -> (c `notElem` [1..15]) ==> (c ^? integralHEXADECIMALNoZero == Nothing)
 integralHEXADECIMALNoZero ::
   (Integral a, HEXADECIMALNoZero d) =>
   Prism'
@@ -646,110 +346,151 @@
 
 -- |
 --
--- >>> 0 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 0
---
--- >>> 1 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 1
---
--- >>> 2 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 2
---
--- >>> 3 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 3
---
--- >>> 4 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 4
---
--- >>> 5 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 5
---
--- >>> 6 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 6
---
--- >>> 7 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 7
---
--- >>> 8 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 8
---
--- >>> 9 ^? integralHEXADECIMAL :: Maybe Digit
--- Just 9
---
--- >>> 10 ^? integralHEXADECIMAL :: Maybe Digit
--- Just A
---
--- >>> 11 ^? integralHEXADECIMAL :: Maybe Digit
--- Just B
+-- >>> 15 ^? integralHEXADECIMAL :: Maybe HEXDigit
+-- Just HEXDigitF
 --
--- >>> 12 ^? integralHEXADECIMAL :: Maybe Digit
--- Just C
+-- >>> integralHEXADECIMAL # HEXDigitF :: Integer
+-- 15
+integralHEXADECIMAL ::
+  (Integral a, HEXADECIMAL d) =>
+  Prism'
+    a
+    d
+integralHEXADECIMAL =
+  associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, dA), (11, dB), (12, dC), (13, dD), (14, dE), (15, dF)]
+
+-- |
+-- >>> integralHEXDigits (256 :: Int)
+-- Right (HEXDigit1 :| [HEXDigit0, HEXDigit0])
 --
--- >>> 13 ^? integralHEXADECIMAL :: Maybe Digit
--- Just D
+-- >>> integralHEXDigits (0 :: Int)
+-- Right (HEXDigit0 :| [])
 --
--- >>> 14 ^? integralHEXADECIMAL :: Maybe Digit
--- Just E
+-- >>> integralHEXDigits (-1 :: Int)
+-- Left (HEXDigit0 :| [])
 --
--- >>> 15 ^? integralHEXADECIMAL :: Maybe Digit
--- Just F
+-- >>> integralHEXDigits (-256 :: Int)
+-- Left (HEXDigitF :| [HEXDigitF])
+integralHEXDigits :: Integral a => a -> Either (NonEmpty HEXDigit) (NonEmpty HEXDigit)
+integralHEXDigits n =
+  if n >= 0
+  then Right . NonEmpty.fromList $ go n []
+  else Left . NonEmpty.fromList $ go (-n - 1) []
+  where
+    go k =
+      let
+        (q, r) = quotRem k 16
+      in
+        (if q == 0 then id else go q) . ((r ^?! integralHEXADECIMAL) :)
+
+-- |
+-- >>> HEXDigitsIntegral (Right (HEXDigit1 :| [HEXDigit0, HEXDigit0])) :: Int
+-- 256
 --
--- >>> integralHEXADECIMAL # Digit0 :: Integer
+-- >>> HEXDigitsIntegral (Right (HEXDigit0 :| [])) :: Int
 -- 0
 --
--- >>> integralHEXADECIMAL # Digit1 :: Integer
--- 1
---
--- >>> integralHEXADECIMAL # Digit2 :: Integer
--- 2
---
--- >>> integralHEXADECIMAL # Digit3 :: Integer
--- 3
---
--- >>> integralHEXADECIMAL # Digit4 :: Integer
--- 4
---
--- >>> integralHEXADECIMAL # Digit5 :: Integer
--- 5
---
--- >>> integralHEXADECIMAL # Digit6 :: Integer
--- 6
---
--- >>> integralHEXADECIMAL # Digit7 :: Integer
--- 7
---
--- >>> integralHEXADECIMAL # Digit8 :: Integer
--- 8
---
--- >>> integralHEXADECIMAL # Digit9 :: Integer
--- 9
---
--- >>> integralHEXADECIMAL # DigitA :: Integer
--- 10
+-- >>> HEXDigitsIntegral (Left (HEXDigit0 :| [])) :: Int
+-- -1
 --
--- >>> integralHEXADECIMAL # DigitB :: Integer
--- 11
+-- >>> HEXDigitsIntegral (Left (HEXDigitF :| [HEXDigitF])) :: Int
+-- -256
+_HEXDigitsIntegral :: Integral a => Either (NonEmpty HEXDigit) (NonEmpty HEXDigit) -> a
+_HEXDigitsIntegral = either (\n -> -(go n) - 1) go
+  where
+    go = foldl' (\b a -> (integralHEXADECIMAL # a) + 16 * b) 0
+
+-- |
 --
--- >>> integralHEXADECIMAL # DigitC :: Integer
--- 12
+-- >>> 15 ^? integralHeXaDeCiMaLNoZero :: Maybe HeXDigit
+-- Just HeXDigitF
 --
--- >>> integralHEXADECIMAL # DigitD :: Integer
--- 13
+-- >>> integralHeXaDeCiMaLNoZero # HeXDigitF :: Integer
+-- 15
+integralHeXaDeCiMaLNoZero ::
+  (Integral a, HeXaDeCiMaLNoZero d) =>
+  Review
+    a
+    d
+integralHeXaDeCiMaLNoZero =
+  unto
+    (outside d1 .~ (\_ -> 1) $
+     outside d2 .~ (\_ -> 2) $
+     outside d3 .~ (\_ -> 3) $
+     outside d4 .~ (\_ -> 4) $
+     outside d5 .~ (\_ -> 5) $
+     outside d6 .~ (\_ -> 6) $
+     outside d7 .~ (\_ -> 7) $
+     outside d8 .~ (\_ -> 8) $
+     outside d9 .~ (\_ -> 9) $
+     outside da .~ (\_ -> 10) $
+     outside dA .~ (\_ -> 10) $
+     outside db .~ (\_ -> 11) $
+     outside dB .~ (\_ -> 11) $
+     outside dc .~ (\_ -> 12) $
+     outside dC .~ (\_ -> 12) $
+     outside dd .~ (\_ -> 13) $
+     outside dD .~ (\_ -> 13) $
+     outside de .~ (\_ -> 14) $
+     outside dE .~ (\_ -> 14) $
+     outside df .~ (\_ -> 15) $
+     outside dF .~ (\_ -> 15) $
+     error "incomplete pattern")
+
+-- |
 --
--- >>> integralHEXADECIMAL # DigitE :: Integer
--- 14
+-- >>> 15 ^? integralHeXaDeCiMaL :: Maybe HeXDigit
+-- Just HeXDigitF
 --
--- >>> integralHEXADECIMAL # DigitF :: Integer
+-- >>> integralHeXaDeCiMaL # HeXDigitF :: Integer
 -- 15
---
--- prop> \c -> (c `notElem` [0..15]) ==> (c ^? integralHEXADECIMAL == Nothing)
-integralHEXADECIMAL ::
-  (Integral a, HEXADECIMAL d) =>
-  Prism'
+integralHeXaDeCiMaL ::
+  (Integral a, HeXaDeCiMaL d) =>
+  Review
     a
     d
-integralHEXADECIMAL =
-  associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, dA), (11, dB), (12, dC), (13, dD), (14, dE), (15, dF)]
+integralHeXaDeCiMaL =
+  unto
+    (outside d0 .~ (\_ -> 0) $
+     outside d1 .~ (\_ -> 1) $
+     outside d2 .~ (\_ -> 2) $
+     outside d3 .~ (\_ -> 3) $
+     outside d4 .~ (\_ -> 4) $
+     outside d5 .~ (\_ -> 5) $
+     outside d6 .~ (\_ -> 6) $
+     outside d7 .~ (\_ -> 7) $
+     outside d8 .~ (\_ -> 8) $
+     outside d9 .~ (\_ -> 9) $
+     outside da .~ (\_ -> 10) $
+     outside dA .~ (\_ -> 10) $
+     outside db .~ (\_ -> 11) $
+     outside dB .~ (\_ -> 11) $
+     outside dc .~ (\_ -> 12) $
+     outside dC .~ (\_ -> 12) $
+     outside dd .~ (\_ -> 13) $
+     outside dD .~ (\_ -> 13) $
+     outside de .~ (\_ -> 14) $
+     outside dE .~ (\_ -> 14) $
+     outside df .~ (\_ -> 15) $
+     outside dF .~ (\_ -> 15) $
+     error "incomplete pattern")
+
+-- |
+-- >>> HeXDigitsIntegral (Right (HeXDigit1 :| [HeXDigit0, HeXDigit0])) :: Int
+-- 256
+--
+-- >>> HeXDigitsIntegral (Right (HeXDigit0 :| [])) :: Int
+-- 0
+--
+-- >>> HeXDigitsIntegral (Left (HeXDigit0 :| [])) :: Int
+-- -1
+--
+-- >>> HeXDigitsIntegral (Left (HeXDigitF :| [HeXDigitF])) :: Int
+-- -256
+_HeXDigitsIntegral :: Integral a => Either (NonEmpty HeXDigit) (NonEmpty HeXDigit) -> a
+_HeXDigitsIntegral = either (\n -> -(go n) - 1) go
+  where
+    go = foldl' (\b a -> (integralHeXaDeCiMaL # a) + 16 * b) 0
 
 ---- not exported
 associatePrism ::
diff --git a/src/Data/Digit/Natural.hs b/src/Data/Digit/Natural.hs
--- a/src/Data/Digit/Natural.hs
+++ b/src/Data/Digit/Natural.hs
@@ -22,7 +22,7 @@
 
 import           Data.Maybe          (Maybe (..))
 
-import           Data.Digit.Digit
+import           Data.Digit.Decimal
 import           Data.Digit.Integral (integralDecimal)
 
 import           Numeric.Natural     (Natural)
@@ -32,40 +32,37 @@
 -- |
 --
 -- >>> _NaturalDigits # 0
--- 0 :| []
+-- DecDigit0 :| []
 --
 -- >>> _NaturalDigits # 1
--- 1 :| []
+-- DecDigit1 :| []
 --
--- >>> _NaturalDigits # 9223372036854775807
--- 9 :| [2,2,3,3,7,2,0,3,6,8,5,4,7,7,5,8,0,7]
+-- >>> _NaturalDigits # 922
+-- DecDigit9 :| [DecDigit2,DecDigit2]
 --
--- >>> (9 :| [2,2,3,3,7,2,0,3,6,8,5,4,7,7,5,8,0,7]) ^? _NaturalDigits
--- Just 9223372036854775807
+-- >>> (DecDigit9 :| [DecDigit2,DecDigit2]) ^? _NaturalDigits
+-- Just 922
 --
--- >>> (1 :| []) ^? _NaturalDigits
+-- >>> (DecDigit1 :| []) ^? _NaturalDigits
 -- Just 1
 --
 -- prop> \x -> digitsToNatural ( naturalToDigits x ) == Just x
 --
-_NaturalDigits :: Prism' (NonEmpty Digit) Natural
+_NaturalDigits :: Prism' (NonEmpty DecDigit) Natural
 _NaturalDigits = prism' naturalToDigits digitsToNatural
 
--- | NonEmpty Digits from a Natural number
+-- |
 --
 -- >>> naturalDigits 0
--- 0 :| []
+-- DecDigit0 :| []
 --
 -- >>> naturalDigits 9
--- 9 :| []
---
--- >>> naturalDigits 393564
--- 3 :| [9,3,5,6,4]
+-- DecDigit9 :| []
 --
--- >>> naturalDigits 9223372036854775807
--- 9 :| [2,2,3,3,7,2,0,3,6,8,5,4,7,7,5,8,0,7]
+-- >>> naturalDigits 393
+-- DecDigit3 :| [DecDigit9,DecDigit3]
 --
-naturalToDigits :: Natural -> NonEmpty Digit
+naturalToDigits :: Natural -> NonEmpty DecDigit
 naturalToDigits n =
   case toDecimalDigits $ fromIntegral n of
     -- toDecimalDigits :: n -> ([n],n)
@@ -77,45 +74,39 @@
 
   where
     t allDigs eXP =
-      replicate (eXP - length allDigs) Digit0
+      replicate (eXP - length allDigs) (d0 # ())
 
     -- EWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW!
     -- But you can't reach this point unless you have a non-zero absolute integral value. So... I dunno.
-    g 0 = Digit0
-    g 1 = Digit1
-    g 2 = Digit2
-    g 3 = Digit3
-    g 4 = Digit4
-    g 5 = Digit5
-    g 6 = Digit6
-    g 7 = Digit7
-    g 8 = Digit8
-    g 9 = Digit9
+    g 0 = d0 # ()
+    g 1 = d1 # ()
+    g 2 = d2 # ()
+    g 3 = d3 # ()
+    g 4 = d4 # ()
+    g 5 = d5 # ()
+    g 6 = d6 # ()
+    g 7 = d7 # ()
+    g 8 = d8 # ()
+    g 9 = d9 # ()
     g _ = error "The universe now has more than ten digits."
 
 -- | Create a number from a list of digits with the integer bounds of the machine.
 --
--- >>> naturalFromDigits (D.x3 :| [D.x4])
+-- >>> digitsToNatural (DecDigit3 :| [DecDigit4])
 -- Just 34
 --
--- >>> naturalFromDigits (D.Digit3 :| [D.Digit9,D.Digit3,D.Digit5,D.Digit6,D.Digit4])
--- Just 393564
---
--- >>> naturalFromDigits (D.x0 :| [])
+-- >>> digitsToNatural (DecDigit0 :| [])
 -- Just 0
 --
--- Int maxBound for Int64
--- >>> naturalFromDigits (D.x9 :| [D.x2,D.x2,D.x3,D.x3,D.x7,D.x2,D.x0,D.x3,D.x6,D.x8,D.x5,D.x4,D.x7,D.x7,D.x5,D.x8,D.x0,D.x7])
+-- >>> digitsToNatural (naturalToDigits (maxBound :: Natural))
 -- Just 9223372036854775807
 --
--- Int maxBound + 1 for Int64
--- >>> naturalFromDigits (D.x9 :| [D.x2,D.x2,D.x3,D.x3,D.x7,D.x2,D.x0,D.x3,D.x6,D.x8,D.x5,D.x4,D.x7,D.x7,D.x5,D.x8,D.x0,D.x8])
+-- >>> digitsToNatural (naturalToDigits $ (maxBound :: Natural) + 1)
 -- Nothing
---
-digitsToNatural :: NonEmpty Digit -> Maybe Natural
+digitsToNatural :: NonEmpty DecDigit -> Maybe Natural
 digitsToNatural = fmap fromIntegral . ifoldrM f 0 . NE.reverse
   where
-    f :: Int -> Digit -> Int -> Maybe Int
+    f :: Int -> DecDigit -> Int -> Maybe Int
     f i d curr =
       let
         next = (integralDecimal # d) * (10 ^ i)
diff --git a/src/Data/Digit/Octal.hs b/src/Data/Digit/Octal.hs
--- a/src/Data/Digit/Octal.hs
+++ b/src/Data/Digit/Octal.hs
@@ -1,81 +1,71 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 module Data.Digit.Octal(
-  OctalNoZero
+  OctDigit(..)
+, OctalNoZero
 , Octal
 , parseOctalNoZero
 , parseOctal
+-- * Prisms
+, _OctDigit0
+, _OctDigit1
+, _OctDigit2
+, _OctDigit3
+, _OctDigit4
+, _OctDigit5
+, _OctDigit6
+, _OctDigit7
+-- * Re-exports
+, module Data.Digit.D0
+, module Data.Digit.D1
+, module Data.Digit.D2
+, module Data.Digit.D3
+, module Data.Digit.D4
+, module Data.Digit.D5
+, module Data.Digit.D6
+, module Data.Digit.D7
 ) where
 
+import Prelude (Eq, Show, Ord, Enum, Bounded)
+import Control.Lens.TH (makePrisms)
 import Text.Parser.Char(CharParsing)
 import Text.Parser.Combinators((<?>), choice)
-import Data.Digit.D0(D0, parse0)
-import Data.Digit.D1(D1, parse1)
-import Data.Digit.D2(D2, parse2)
-import Data.Digit.D3(D3, parse3)
-import Data.Digit.D4(D4, parse4)
-import Data.Digit.D5(D5, parse5)
-import Data.Digit.D6(D6, parse6)
-import Data.Digit.D7(D7, parse7)
+import Data.Digit.D0
+import Data.Digit.D1
+import Data.Digit.D2
+import Data.Digit.D3
+import Data.Digit.D4
+import Data.Digit.D5
+import Data.Digit.D6
+import Data.Digit.D7
 
--- $setup
--- >>> import Text.Parsec(parse, ParseError, eof)
--- >>> import Data.Void(Void)
--- >>> import Data.Digit.Digit
--- >>> import Papa
+data OctDigit
+  = OctDigit0
+  | OctDigit1
+  | OctDigit2
+  | OctDigit3
+  | OctDigit4
+  | OctDigit5
+  | OctDigit6
+  | OctDigit7
+  deriving (Show, Eq, Ord, Enum, Bounded)
 
+makePrisms ''OctDigit
+
+instance D0 OctDigit where; d0 = _OctDigit0
+instance D1 OctDigit where; d1 = _OctDigit1
+instance D2 OctDigit where; d2 = _OctDigit2
+instance D3 OctDigit where; d3 = _OctDigit3
+instance D4 OctDigit where; d4 = _OctDigit4
+instance D5 OctDigit where; d5 = _OctDigit5
+instance D6 OctDigit where; d6 = _OctDigit6
+instance D7 OctDigit where; d7 = _OctDigit7
+
 type OctalNoZero d =
   (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d)
 
--- |
---
--- >>> parse (parseOctalNoZero <* eof) "test" "1" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseOctalNoZero "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseOctalNoZero <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseOctalNoZero "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseOctalNoZero <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseOctalNoZero "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseOctalNoZero <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseOctalNoZero "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseOctalNoZero <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseOctalNoZero "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseOctalNoZero <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseOctalNoZero "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseOctalNoZero <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseOctalNoZero "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> isn't _Right (parse parseOctalNoZero "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "1234567") ==> isn't _Right (parse parseOctalNoZero "test" [c] :: Either ParseError Digit)
 parseOctalNoZero ::
   (OctalNoZero d, CharParsing p) =>
   p d
@@ -94,60 +84,6 @@
 type Octal d =
   (D0 d, OctalNoZero d)
 
--- |
---
--- >>> parse (parseOctal <* eof) "test" "0" :: Either ParseError Digit
--- Right 0
---
--- >>> parse (parseOctal <* eof) "test" "0" :: Either ParseError Digit
--- Right 0
---
--- >>> parse parseOctal "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse parseOctal "test" "1xyz" :: Either ParseError Digit
--- Right 1
---
--- >>> parse (parseOctal <* eof) "test" "2" :: Either ParseError Digit
--- Right 2
---
--- >>> parse parseOctal "test" "2xyz" :: Either ParseError Digit
--- Right 2
---
--- >>> parse (parseOctal <* eof) "test" "3" :: Either ParseError Digit
--- Right 3
---
--- >>> parse parseOctal "test" "3xyz" :: Either ParseError Digit
--- Right 3
---
--- >>> parse (parseOctal <* eof) "test" "4" :: Either ParseError Digit
--- Right 4
---
--- >>> parse parseOctal "test" "4xyz" :: Either ParseError Digit
--- Right 4
---
--- >>> parse (parseOctal <* eof) "test" "5" :: Either ParseError Digit
--- Right 5
---
--- >>> parse parseOctal "test" "5xyz" :: Either ParseError Digit
--- Right 5
---
--- >>> parse (parseOctal <* eof) "test" "6" :: Either ParseError Digit
--- Right 6
---
--- >>> parse parseOctal "test" "6xyz" :: Either ParseError Digit
--- Right 6
---
--- >>> parse (parseOctal <* eof) "test" "7" :: Either ParseError Digit
--- Right 7
---
--- >>> parse parseOctal "test" "7xyz" :: Either ParseError Digit
--- Right 7
---
--- >>> isn't _Right (parse parseOctal "test" "xyz" :: Either ParseError Digit)
--- True
---
--- prop> \c -> (c `notElem` "01234567") ==> isn't _Right (parse parseOctal "test" [c] :: Either ParseError Digit)
 parseOctal ::
   (Octal d, CharParsing p) =>
   p d
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -6,22 +6,22 @@
 
 import Data.Digit
 import Numeric.Natural (Natural)
-import Prelude (maxBound)
+import Prelude (minBound, maxBound)
 import Papa hiding (re)
 import Hedgehog(Property, Gen, forAll, property, assert, (===))
 import Test.Tasty(TestTree, defaultMain, testGroup)
 import Test.Tasty.Hedgehog(testProperty)
 import Test.Tasty.HUnit(testCase, (@?=))
-import qualified Hedgehog.Gen as Gen(choice, integral, unicode, hexit, filter)
-import qualified Hedgehog.Range as Range(linear)
+import qualified Hedgehog.Gen as Gen
+import qualified Hedgehog.Range as Range
 import Text.Parsec(parse, ParseError, Parsec, eof)
 
 testPrism ::
   (Show x, Eq x) =>
   Gen x
   -> String
-  -> Prism' x Digit
-  -> [(x, Digit)]
+  -> Prism' x HeXDigit
+  -> [(x, HeXDigit)]
   -> [TestTree]
 testPrism g n p x =
   testProperty
@@ -29,14 +29,14 @@
     (
       property $
         do  c <- forAll . Gen.filter (`notElem` (map fst x)) $ g
-            (c ^? p :: Maybe Digit) === Nothing
+            (c ^? p :: Maybe HeXDigit) === Nothing
     ) :
     (
       x >>= \(c, d) ->
         [
           testCase
             (n ++ " prism ->")
-            ((c ^? p :: Maybe Digit) @?= Just d)
+            ((c ^? p :: Maybe HeXDigit) @?= Just d)
         , testCase
             (n ++ " prism <-")
             (p # d @?= c)
@@ -45,8 +45,8 @@
 
 testParser ::
   String
-  -> Parsec String () Digit
-  -> [(Char, Digit)]
+  -> Parsec String () HeXDigit
+  -> [(Char, HeXDigit)]
   -> [TestTree]
 testParser n p x =
     (
@@ -56,7 +56,7 @@
             (
               property $
                 do  c <- forAll . Gen.filter (`notElem` (map fst x)) . Gen.choice $ [Gen.hexit, Gen.unicode]
-                    assert (isLeft (parse p (n' ++ " test") [c] :: Either ParseError Digit))
+                    assert (isLeft (parse p (n' ++ " test") [c] :: Either ParseError HeXDigit))
             )
     ) :
     (
@@ -65,27 +65,27 @@
           let n' = n ++ " parses exactly one character"
           in  testCase
                 n'
-                ((parse (p <* eof) (n' ++ " test") [c] :: Either ParseError Digit) @?= Right d)
+                ((parse (p <* eof) (n' ++ " test") [c] :: Either ParseError HeXDigit) @?= Right d)
         , let n' = n ++ " parses the correct digit"
           in  testCase
                 n'
-                ((parse p (n' ++ "test") (c:"xyz") :: Either ParseError Digit) @?= Right d)
+                ((parse p (n' ++ "test") (c:"xyz") :: Either ParseError HeXDigit) @?= Right d)
             ]
     )
 
 integralPrism ::
   (Show n, Integral n) =>
   String
-  -> Prism' n Digit
-  -> [(n, Digit)]
+  -> Prism' n HeXDigit
+  -> [(n, HeXDigit)]
   -> [TestTree]
 integralPrism =
   testPrism (Gen.choice [Gen.integral (Range.linear 0 9), Gen.integral (Range.linear 10 99999), Gen.integral (Range.linear (-1) (-99999))])
 
 charPrism ::
   String
-  -> Prism' Char Digit
-  -> [(Char, Digit)]
+  -> Prism' Char HeXDigit
+  -> [(Char, HeXDigit)]
   -> [TestTree]
 charPrism =
   testPrism (Gen.choice [Gen.hexit, Gen.unicode])
@@ -103,83 +103,131 @@
   [ testProperty "Natural <-> NonEmpty Digit" prop_natural_digits_roundtrip
   ]
 
+prop_integer_X :: (Integer -> a) -> (a -> Integer) -> Property
+prop_integer_X iToX xToI =
+  property $ do
+    n <- forAll .
+      Gen.integral $
+        Range.constant
+          (fromIntegral (minBound :: Int))
+          (fromIntegral (maxBound :: Int))
+    xToI (iToX n) === n
+
+prop_X_integer
+  :: (Eq a, Show a)
+  => Gen a
+  -> (Integer -> Either (NonEmpty a) (NonEmpty a))
+  -> (Either (NonEmpty a) (NonEmpty a) -> Integer)
+  -> Property
+prop_X_integer genX iToX xToI =
+  property $ do
+    let digits = Gen.nonEmpty (Range.constant 1 50) genX
+    ds <- forAll $ Gen.choice [Left <$> digits, Right <$> digits]
+    xToI (iToX (xToI ds)) === xToI ds
+
+toFromIntegralTests :: TestTree
+toFromIntegralTests =
+  testGroup "To and from integers"
+  [ testProperty "Integer <-> BinDigit" $
+      prop_integer_X integralBinDigits binDigitsIntegral
+  , testProperty "BinDigit <-> Integer" $
+      prop_X_integer (Gen.element enumBinary) integralBinDigits binDigitsIntegral
+  , testProperty "Integer <-> OctDigit" $
+      prop_integer_X integralOctDigits octDigitsIntegral
+  , testProperty "OctDigit <-> Integer" $
+      prop_X_integer (Gen.element enumOctal) integralOctDigits octDigitsIntegral
+  , testProperty "Integer <-> DecDigit" $
+      prop_integer_X integralDecDigits decDigitsIntegral
+  , testProperty "DecDigit <-> Integer" $
+      prop_X_integer (Gen.element enumDecimal) integralDecDigits decDigitsIntegral
+  , testProperty "Integer <-> HexDigit" $
+      prop_integer_X integralHexDigits hexDigitsIntegral
+  , testProperty "HexDigit <-> Integer" $
+      prop_X_integer (Gen.element enumHexadecimal) integralHexDigits hexDigitsIntegral
+  , testProperty "Integer <-> HEXDigit" $
+      prop_integer_X integralHEXDigits _HEXDigitsIntegral
+  , testProperty "HEXDigit <-> Integer" $
+      prop_X_integer (Gen.element enumHEXADECIMAL) integralHEXDigits _HEXDigitsIntegral
+  ]
+
 main ::
   IO ()
 main = defaultMain $
   testGroup "All Digit Tests"
     [ digitBaseTests
     , digitNaturalTests
+    , toFromIntegralTests
     ]
 
 digitBaseTests :: TestTree
 digitBaseTests =
   testGroup "digit parser/prism tests" $
-    let q0  = ('0', Digit0)
-        q1  = ('1', Digit1)
-        q2  = ('2', Digit2)
-        q3  = ('3', Digit3)
-        q4  = ('4', Digit4)
-        q5  = ('5', Digit5)
-        q6  = ('6', Digit6)
-        q7  = ('7', Digit7)
-        q8  = ('8', Digit8)
-        q9  = ('9', Digit9)
-        qa  = ('a', Digita)
-        qb  = ('b', Digitb)
-        qc  = ('c', Digitc)
-        qd  = ('d', Digitd)
-        qe  = ('e', Digite)
-        qf  = ('f', Digitf)
-        qA  = ('A', DigitA)
-        qB  = ('B', DigitB)
-        qC  = ('C', DigitC)
-        qD  = ('D', DigitD)
-        qE  = ('E', DigitE)
-        qF  = ('F', DigitF)
-        r0 :: (Integer, Digit)
-        r0  = (0  , Digit0)
-        r1 :: (Integer, Digit)
-        r1  = (1  , Digit1)
-        r2 :: (Integer, Digit)
-        r2  = (2  , Digit2)
-        r3 :: (Integer, Digit)
-        r3  = (3  , Digit3)
-        r4 :: (Integer, Digit)
-        r4  = (4  , Digit4)
-        r5 :: (Integer, Digit)
-        r5  = (5  , Digit5)
-        r6 :: (Integer, Digit)
-        r6  = (6  , Digit6)
-        r7 :: (Integer, Digit)
-        r7  = (7  , Digit7)
-        r8 :: (Integer, Digit)
-        r8  = (8  , Digit8)
-        r9 :: (Integer, Digit)
-        r9  = (9  , Digit9)
-        ra :: (Integer, Digit)
-        ra =  (10 , Digita)
-        rb :: (Integer, Digit)
-        rb =  (11 , Digitb)
-        rc :: (Integer, Digit)
-        rc =  (12 , Digitc)
-        rd :: (Integer, Digit)
-        rd =  (13 , Digitd)
-        re :: (Integer, Digit)
-        re =  (14 , Digite)
-        rf :: (Integer, Digit)
-        rf =  (15 , Digitf)
-        rA :: (Integer, Digit)
-        rA =  (10 , DigitA)
-        rB :: (Integer, Digit)
-        rB =  (11 , DigitB)
-        rC :: (Integer, Digit)
-        rC =  (12 , DigitC)
-        rD :: (Integer, Digit)
-        rD =  (13 , DigitD)
-        rE :: (Integer, Digit)
-        rE =  (14 , DigitE)
-        rF :: (Integer, Digit)
-        rF =  (15 , DigitF)
+    let q0  = ('0', HeXDigit0)
+        q1  = ('1', HeXDigit1)
+        q2  = ('2', HeXDigit2)
+        q3  = ('3', HeXDigit3)
+        q4  = ('4', HeXDigit4)
+        q5  = ('5', HeXDigit5)
+        q6  = ('6', HeXDigit6)
+        q7  = ('7', HeXDigit7)
+        q8  = ('8', HeXDigit8)
+        q9  = ('9', HeXDigit9)
+        qa  = ('a', HeXDigita)
+        qb  = ('b', HeXDigitb)
+        qc  = ('c', HeXDigitc)
+        qd  = ('d', HeXDigitd)
+        qe  = ('e', HeXDigite)
+        qf  = ('f', HeXDigitf)
+        qA  = ('A', HeXDigitA)
+        qB  = ('B', HeXDigitB)
+        qC  = ('C', HeXDigitC)
+        qD  = ('D', HeXDigitD)
+        qE  = ('E', HeXDigitE)
+        qF  = ('F', HeXDigitF)
+        r0 :: (Integer, HeXDigit)
+        r0  = (0  , HeXDigit0)
+        r1 :: (Integer, HeXDigit)
+        r1  = (1  , HeXDigit1)
+        r2 :: (Integer, HeXDigit)
+        r2  = (2  , HeXDigit2)
+        r3 :: (Integer, HeXDigit)
+        r3  = (3  , HeXDigit3)
+        r4 :: (Integer, HeXDigit)
+        r4  = (4  , HeXDigit4)
+        r5 :: (Integer, HeXDigit)
+        r5  = (5  , HeXDigit5)
+        r6 :: (Integer, HeXDigit)
+        r6  = (6  , HeXDigit6)
+        r7 :: (Integer, HeXDigit)
+        r7  = (7  , HeXDigit7)
+        r8 :: (Integer, HeXDigit)
+        r8  = (8  , HeXDigit8)
+        r9 :: (Integer, HeXDigit)
+        r9  = (9  , HeXDigit9)
+        ra :: (Integer, HeXDigit)
+        ra =  (10 , HeXDigita)
+        rb :: (Integer, HeXDigit)
+        rb =  (11 , HeXDigitb)
+        rc :: (Integer, HeXDigit)
+        rc =  (12 , HeXDigitc)
+        rd :: (Integer, HeXDigit)
+        rd =  (13 , HeXDigitd)
+        re :: (Integer, HeXDigit)
+        re =  (14 , HeXDigite)
+        rf :: (Integer, HeXDigit)
+        rf =  (15 , HeXDigitf)
+        rA :: (Integer, HeXDigit)
+        rA =  (10 , HeXDigitA)
+        rB :: (Integer, HeXDigit)
+        rB =  (11 , HeXDigitB)
+        rC :: (Integer, HeXDigit)
+        rC =  (12 , HeXDigitC)
+        rD :: (Integer, HeXDigit)
+        rD =  (13 , HeXDigitD)
+        rE :: (Integer, HeXDigit)
+        rE =  (14 , HeXDigitE)
+        rF :: (Integer, HeXDigit)
+        rF =  (15 , HeXDigitF)
     in  concat [
           charPrism "charBinaryNoZero" charBinaryNoZero [q1]
         , charPrism "charBinary" charBinary [q0, q1]
