diff --git a/data-textual.cabal b/data-textual.cabal
--- a/data-textual.cabal
+++ b/data-textual.cabal
@@ -1,5 +1,5 @@
 Name: data-textual
-Version: 0.1
+Version: 0.2
 Category: Data, Text
 Stability: experimental
 Synopsis: Human-friendly textual representations.
@@ -30,14 +30,15 @@
     bytestring >= 0.10,
     text,
     tagged >= 0.2,
-    text-latin1 >= 0.2,
-    text-printer >= 0.3,
+    text-latin1 >= 0.3,
+    text-printer >= 0.4,
     parsers >= 0.5
   Hs-Source-Dirs: src
   GHC-Options: -Wall
   Exposed-Modules:
     Data.Textual
-    Data.Textual.Numerals
+    Data.Textual.Integral
+    Data.Textual.Fractional
 
 Test-Suite tests
   Default-Language: Haskell2010
diff --git a/src/Data/Textual.hs b/src/Data/Textual.hs
--- a/src/Data/Textual.hs
+++ b/src/Data/Textual.hs
@@ -41,6 +41,18 @@
   , aWord16
   , aWord32
   , aWord64
+  , aRatio
+  , aRatioOf
+  , aRational
+  , aFixed
+  , aFixedOf
+  , aUni
+  , aDeci
+  , aCenti
+  , aMilli
+  , aMicro
+  , aNano
+  , aPico
   , aFloat
   , aDouble
   , aMaybe
@@ -91,6 +103,9 @@
 import Data.Monoid (mempty)
 import Data.Int
 import Data.Word
+import Data.Ratio (Ratio)
+import Data.Fixed (Fixed, HasResolution,
+                   Uni, Centi, Deci, Milli, Micro, Nano, Pico)
 import Data.List (stripPrefix)
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Char8 as BS8
@@ -99,10 +114,12 @@
 import qualified Data.Text as TS
 import qualified Data.Text.Lazy as TL
 import Data.Text.Lazy.Encoding (decodeUtf8)
-import Data.Textual.Numerals
+import Data.Textual.Integral
+import Data.Textual.Fractional
 import Control.Applicative
 import qualified Text.Printer as TP
-import qualified Text.Printer.Numerals as TP
+import qualified Text.Printer.Integral as TP
+import qualified Text.Printer.Fractional as TP
 import Text.Parser.Combinators (Parsing, (<?>))
 import qualified Text.Parser.Combinators as PC
 import Text.Parser.Char (CharParsing)
@@ -172,6 +189,14 @@
   print = TP.nnDecimal
   {-# INLINE print #-}
 
+instance Integral α ⇒ Printable (Ratio α) where
+  print = TP.fraction
+  {-# INLINE print #-}
+
+instance HasResolution α ⇒ Printable (Fixed α) where
+  print = TP.string7 . show
+  {-# INLINE print #-}
+
 instance Printable Float where
   print = TP.string7 . show
   {-# INLINE print #-}
@@ -275,6 +300,14 @@
   textual = nnBounded Decimal
   {-# INLINE textual #-}
 
+instance Integral α ⇒ Textual (Ratio α) where
+  textual = fraction
+  {-# INLINE textual #-}
+
+instance HasResolution α ⇒ Textual (Fixed α) where
+  textual = fractional
+  {-# INLINE textual #-}
+
 -- | Hint the type system about the type of the first argument.
 hintType ∷ α → Proxy α → α
 hintType a _ = a
@@ -343,6 +376,54 @@
 -- | 'Word64' proxy value.
 aWord64 ∷ Proxy Word64
 aWord64 = Proxy
+
+-- | 'Ratio' proxy value.
+aRatio ∷ Proxy Ratio
+aRatio = Proxy
+
+-- | 'Ratio' /α/ proxy value.
+aRatioOf ∷ Proxy α → Proxy (Ratio α)
+aRatioOf _ = Proxy
+
+-- | 'Rational' proxy value.
+aRational ∷ Proxy Rational
+aRational = Proxy
+
+-- | 'Fixed' proxy value.
+aFixed ∷ Proxy Fixed
+aFixed = Proxy
+
+-- | 'Fixed' /α/ proxy value.
+aFixedOf ∷ Proxy α → Proxy (Fixed α)
+aFixedOf _ = Proxy
+
+-- | 'Uni' proxy value.
+aUni ∷ Proxy Uni
+aUni = Proxy
+
+-- | 'Deci' proxy value.
+aDeci ∷ Proxy Deci
+aDeci = Proxy
+
+-- | 'Centi' proxy value.
+aCenti ∷ Proxy Centi
+aCenti = Proxy
+
+-- | 'Milli' proxy value.
+aMilli ∷ Proxy Milli
+aMilli = Proxy
+
+-- | 'Micro' proxy value.
+aMicro ∷ Proxy Micro
+aMicro = Proxy
+
+-- | 'Nano' proxy value.
+aNano ∷ Proxy Nano
+aNano = Proxy
+
+-- | 'Pico' proxy value.
+aPico ∷ Proxy Pico
+aPico = Proxy
 
 -- | 'Float' proxy value.
 aFloat ∷ Proxy Float
diff --git a/src/Data/Textual/Fractional.hs b/src/Data/Textual/Fractional.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Textual/Fractional.hs
@@ -0,0 +1,138 @@
+{-# LANGUAGE UnicodeSyntax #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE LambdaCase #-}
+
+-- | Parsers for fractions.
+module Data.Textual.Fractional
+  (
+  -- * Positional numeral systems
+    PositionalSystem(..)
+  , Binary(..)
+  , Octal(..)
+  , Decimal(..)
+  , Hexadecimal(..)
+  , UpHex(..)
+  , LowHex(..)
+  -- * Sign
+  , Sign(..)
+  , applySign
+  , optMinus
+  , optSign
+  -- * Optionality characteristic
+  , Optional(..)
+  , isOptional
+  , isRequired
+  -- * Fraction parsers
+  , optSlash
+  , fraction'
+  , fraction
+  -- * s-fraction parsers
+  , decExpSign
+  , hexExpSign
+  , fractional'
+  , fractional
+  ) where
+
+import Data.Maybe (isJust)
+import Data.Ratio ((%))
+import Control.Applicative
+import Text.Printer.Fractional (Optional(..), isOptional, isRequired)
+import Text.Parser.Combinators ((<?>), unexpected)
+import Text.Parser.Char (CharParsing)
+import qualified Text.Parser.Char as PC
+import Data.Textual.Integral
+
+-- | Accept a slash and return 'Required'. Otherwise return 'Optional'.
+optSlash ∷ (Monad μ, CharParsing μ) ⇒ μ Optional
+optSlash = maybe Optional (const Required) <$> optional (PC.char '/')
+
+-- | Parse a fraction. The numerator and the denominator are expected to be
+--   written in the specified positional numeral system.
+fraction' ∷ (PositionalSystem s, Fractional α, Monad μ, CharParsing μ)
+          ⇒ μ Sign -- ^ Sign parser
+          → s
+          → μ Optional -- ^ Numerator/denominator separator parser
+          → μ α
+fraction' neg s den = (<?> "fraction") $ do
+  n ← number' neg s <?> "numerator"
+  den >>= \case
+    Optional →
+      return $ fromInteger n
+    Required → do
+      d ← (<?> "denominator") $ do
+        d ← nonNegative s
+        if d == 0 then unexpected "zero denominator"
+                  else return d
+      return $ fromRational $ n % d
+
+-- | A shorthand for 'fraction'' 'optMinus' 'Decimal' 'optSlash'.
+fraction ∷ (Fractional α, Monad μ, CharParsing μ) ⇒ μ α
+fraction = fraction' optMinus Decimal optSlash
+
+-- | Start of a decimal exponent. Accepts /'e'/ or /'E'/ followed by
+--   an optional sign. Otherwise 'Nothing' is returned.
+decExpSign ∷ (Monad μ, CharParsing μ) ⇒ μ (Maybe Sign)
+decExpSign = optional (PC.oneOf "eE") >>= \case
+               Nothing → return Nothing
+               Just _  → Just <$> optSign
+
+-- | Start of a hexadecimal exponent. Accepts /'p'/ or /'P'/ followed by
+--   an optional sign. Otherwise 'Nothing' is returned.
+hexExpSign ∷ (Monad μ, CharParsing μ) ⇒ μ (Maybe Sign)
+hexExpSign = optional (PC.oneOf "pP") >>= \case
+               Nothing → return Nothing
+               Just _  → Just <$> optSign
+
+-- | /s/-fraction parser.
+fractional' ∷ (PositionalSystem s, Fractional α, Monad μ, CharParsing μ)
+            ⇒ μ Sign -- ^ Sign parser.
+            → s
+            → Optional -- ^ Whether the integer part is optional.
+            → μ () -- ^ Dot parser.
+            → μ (Maybe Sign) -- ^ Exponent start parser.
+            → μ α
+fractional' neg s ip dot eneg = (<?> (systemName s ++ "-fraction")) $ do
+    sign ← neg <?> "sign"
+    (i, f, fDigits) ← do
+      let integral = do
+            i ← nonNegative s <?> "integer part"
+            ((i, ) . isJust) <$> optional dot
+      (i, hasF) ← case ip of
+        Optional → optional dot >>= \case
+          Nothing → integral
+          Just _ → return (0, True)
+        Required → integral
+      (f, fDigits) ←
+        if hasF
+        then do
+          let go !ds !f = optional digit >>= \case
+                            Just d  → go (ds + 1) (f * radix + d)
+                            Nothing → return (f, ds) 
+          digit >>= go (1 ∷ Int) <?> "fractional part"
+        else
+          return (0, 0)
+      return (i, f, fDigits)
+    (<?> "exponent") $ eneg >>= \case
+      Nothing | f == 0    → return $ fromInteger $ applySign sign i
+              | otherwise → return $ fromRational
+                                   $ applySign sign
+                                   $ fromInteger i + f % radix ^ fDigits
+      Just esign → do
+        e ← nnBounded Decimal
+        return $ applySign sign $ case esign of
+          NonNegative → case e - fDigits of
+            e₁ | e₁ >= 0   → fromInteger $ i * radix ^ e + f * radix ^ e₁
+               | otherwise → fromRational
+                           $ fromInteger (i * radix ^ e)
+                           + i % radix ^ negate e₁
+          NonPositive → fromRational
+                      $ i % (radix ^ e) + f % radix ^ (fDigits + e)
+  where 
+    radix = radixIn s
+    digit = digitIn s
+
+-- | Decimal fraction parser.
+fractional ∷ (Monad μ, Fractional α, CharParsing μ) ⇒ μ α
+fractional = fractional' optMinus Decimal Required
+                         (PC.char '.' *> pure ()) decExpSign
diff --git a/src/Data/Textual/Integral.hs b/src/Data/Textual/Integral.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Textual/Integral.hs
@@ -0,0 +1,1648 @@
+{-# LANGUAGE UnicodeSyntax #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-- | Parsers for integral numbers written in positional numeral systems.
+module Data.Textual.Integral
+  (
+  -- * Positional numeral systems
+    PositionalSystem(..)
+  , BitSystem(..)
+  , Binary(..)
+  , Octal(..)
+  , Decimal(..)
+  , Hexadecimal(..)
+  , LowHex(..)
+  , UpHex(..)
+  -- * Single digits
+  , digitIn
+  , nzDigitIn
+  , binDigit
+  , nzBinDigit
+  , octDigit
+  , nzOctDigit
+  , decDigit
+  , nzDecDigit
+  , hexDigit
+  , nzHexDigit
+  , lowHexDigit
+  , nzLowHexDigit
+  , upHexDigit
+  , nzUpHexDigit
+  -- * Numbers
+  , nonNegative
+  , nnCompact
+  , nnUpTo
+  , nncUpTo
+  , nnBounded
+  , nncBounded
+  , nnBits
+  , nncBits
+  , nnBitsUpTo
+  , nncBitsUpTo
+  , nnbBits
+  , nncbBits
+  , nonPositive
+  , npCompact
+  , npUpTo
+  , npcUpTo
+  , npBounded
+  , npcBounded
+  , npBits
+  , npcBits
+  , npBitsUpTo
+  , npcBitsUpTo
+  , npbBits
+  , npcbBits
+  , Sign(..)
+  , applySign
+  , optMinus
+  , optSign
+  , number'
+  , number
+  , compact'
+  , compact
+  , numberUpTo'
+  , numberUpTo
+  , compactUpTo'
+  , compactUpTo
+  , bounded'
+  , bounded
+  , cBounded'
+  , cBounded
+  , bits'
+  , bits
+  , cBits'
+  , cBits
+  , bitsUpTo'
+  , bitsUpTo
+  , cBitsUpTo'
+  , cBitsUpTo
+  , bBits'
+  , bBits
+  , cbBits'
+  , cbBits
+  ) where
+
+import Data.Typeable (Typeable)
+import Data.Int
+import Data.Word
+import Data.Bits (Bits(..))
+import Control.Applicative
+import Text.Printer.Integral (
+         PositionalSystem(..), BitSystem(..),
+         Binary(..), Octal(..), Decimal(..), Hexadecimal(..),
+         LowHex(..), UpHex(..))
+import Text.Parser.Combinators (Parsing, (<?>))
+import qualified Text.Parser.Combinators as PC
+import Text.Parser.Char (CharParsing)
+import qualified Text.Parser.Char as PC
+
+-- | Parse a digit of the specified positional numeral system.
+digitIn ∷ (PositionalSystem s, Num α, CharParsing μ) ⇒ s → μ α
+digitIn s  =  unsafeFromDigitIn s <$> PC.satisfy (isDigitIn s)
+          <?> systemName s ++ " digit"
+{-# INLINE digitIn #-}
+
+-- | Parse a non-zero digit of the specified positional numeral system.
+nzDigitIn ∷ (PositionalSystem s, Num α, CharParsing μ) ⇒ s → μ α
+nzDigitIn s  =  unsafeFromDigitIn s <$> PC.satisfy (isNzDigitIn s)
+            <?> "non-zero " ++ systemName s ++ " digit"
+{-# INLINE nzDigitIn #-}
+
+-- | Parse a binary digit.
+binDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+binDigit = digitIn Binary
+{-# INLINE binDigit #-}
+
+-- | Parse a non-zero binary digit (/'1'/).
+nzBinDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+nzBinDigit = nzDigitIn Binary
+{-# INLINE nzBinDigit #-}
+
+-- | Parse a decimal digit.
+decDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+decDigit = digitIn Decimal
+{-# INLINE decDigit #-}
+
+-- | Parse a non-zero decimal digit.
+nzDecDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+nzDecDigit = nzDigitIn Decimal
+{-# INLINE nzDecDigit #-}
+
+-- | Parse an octal digit.
+octDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+octDigit = digitIn Octal
+{-# INLINE octDigit #-}
+
+-- | Parse a non-zero octal digit.
+nzOctDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+nzOctDigit = nzDigitIn Octal
+{-# INLINE nzOctDigit #-}
+
+-- | Parse a hexadecimal digit.
+hexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+hexDigit = digitIn Hexadecimal
+{-# INLINE hexDigit #-}
+
+-- | Parse a non-zero hexadecimal digit.
+nzHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+nzHexDigit = nzDigitIn Hexadecimal
+{-# INLINE nzHexDigit #-}
+
+-- | Parse a lower case hexadecimal digit.
+lowHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+lowHexDigit = digitIn LowHex
+{-# INLINE lowHexDigit #-}
+
+-- | Parse a non-zero lower case hexadecimal digit.
+nzLowHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+nzLowHexDigit = nzDigitIn LowHex
+{-# INLINE nzLowHexDigit #-}
+
+-- | Parse an upper case hexadecimal digit.
+upHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+upHexDigit = digitIn UpHex
+{-# INLINE upHexDigit #-}
+
+-- | Parse a non-zero upper case hexadecimal digit.
+nzUpHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
+nzUpHexDigit = nzDigitIn UpHex
+{-# INLINE nzUpHexDigit #-}
+
+-- | Parse a non-negative number written in the specified positional
+--   numeral system.
+nonNegative ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
+nonNegative s = digit >>= go <?> systemName s ++ " digits"
+  where go !r = optional digit >>= \case
+                  Just d  → go (r * radix + d)
+                  Nothing → return r
+        radix = radixIn s
+        digit = digitIn s
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
+{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
+{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
+{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-negative number written in the specified positional
+--   numeral system. Leading zeroes are not allowed.
+nnCompact ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
+nnCompact s = (<?> systemName s ++ " digits") $ digitIn s >>= \case
+                0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                      Just _  → PC.unexpected "leading zero"
+                      Nothing → return 0
+                r → go $ fromIntegral (r ∷ Word)
+  where go !r = optional digit >>= \case
+                  Just d  → go (r * radix + d)
+                  Nothing → return r
+        radix = radixIn s
+        digit = digitIn s
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
+{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
+{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
+{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+moreThan ∷ CharParsing μ ⇒ Int → μ α
+moreThan n = PC.unexpected
+           $ "more than " ++ show n ++
+             case n of
+               1 → " digit"
+               _ → " digits"
+{-# INLINE moreThan #-}
+
+-- | Parse a non-negative number written in the specified positional
+--   numeral system (up to /n/ digits).
+nnUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → Int → μ α
+nnUpTo _ n | n <= 0 = empty
+nnUpTo s n = digit >>= go (n - 1) <?> systemName s ++ " digits"
+  where go 0 !r = optional (PC.satisfy $ isDigitIn s) >>= \case
+                    Just _  → moreThan n
+                    Nothing → return r
+        go l !r = optional digit >>= \case
+                    Just d  → go (l - 1) (r * radix + d)
+                    Nothing → return r
+        radix   = radixIn s
+        digit   = digitIn s
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int #-}
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int8 #-}
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int16 #-}
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int32 #-}
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int64 #-}
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word #-}
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word8 #-}
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word16 #-}
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word32 #-}
+{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word64 #-}
+{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
+{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
+{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → Int → μ α #-}
+{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
+{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
+{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
+
+-- | Parse a non-negative number written in the specified positional
+--   numeral system (up to /n/ digits). Leading zeroes are not allowed.
+nncUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → Int → μ α
+nncUpTo _ n | n <= 0 = empty
+nncUpTo s n = (<?> systemName s ++ " digits") $ digitIn s >>= \case
+                0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                      Just _  → PC.unexpected "leading zero"
+                      Nothing → return 0
+                r → go (n - 1) $ fromIntegral (r ∷ Word)
+  where go 0 !r = optional (PC.satisfy $ isDigitIn s) >>= \case
+                    Just _  → moreThan n
+                    Nothing → return r
+        go l !r = optional digit >>= \case
+                    Just d  → go (l - 1) (r * radix + d)
+                    Nothing → return r
+        radix   = radixIn s
+        digit   = digitIn s
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int #-}
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int8 #-}
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int16 #-}
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int32 #-}
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int64 #-}
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word #-}
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word8 #-}
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word16 #-}
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word32 #-}
+{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word64 #-}
+{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
+{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
+{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → Int → μ α #-}
+{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
+{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
+{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
+
+-- | Parse a non-negative number written in the specified positional
+--   numeral system, failing on overflow.
+nnBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
+             Monad μ, CharParsing μ) ⇒ s → μ α
+nnBounded s = digit >>= go <?> systemName s ++ " digits"
+  where (q, r) = quotRem maxBound radix
+        go !n  = optional digit >>= \case
+                   Just n1 → if n < q || (n == q && n1 <= r)
+                             then go (n * radix + n1)
+                             else fail "out of bounds"
+                   Nothing → return n
+        radix  = radixIn s
+        digit  = digitIn s
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
+{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
+{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
+{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-negative number written in the specified positional
+--   numeral system, failing on overflow. Leading zeroes are not allowed.
+nncBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
+              Monad μ, CharParsing μ) ⇒ s → μ α
+nncBounded s = (<?> systemName s ++ " digits") $ digit >>= \case
+                 0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                       Just _  → PC.unexpected "leading zero"
+                       Nothing → return 0
+                 n → go n
+  where (q, r) = quotRem maxBound radix
+        go !n  = optional digit >>= \case
+                   Just d  → if n < q || (n == q && d <= r)
+                             then go (n * radix + d)
+                             else fail "out of bounds"
+                   Nothing → return n
+        radix  = radixIn s
+        digit  = digitIn s
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
+{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
+{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
+{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-negative binary number written in the specified
+--   positional numeral system.
+nnBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
+nnBits s = digit >>= go <?> systemName s ++ " digits"
+  where go !r     = optional digit >>= \case
+                      Just d  → go ((r `shiftL` digitBits) .|. d)
+                      Nothing → return r
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
+{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
+{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-negative binary number written in the specified
+--   positional numeral system. Leading zeroes are not allowed.
+nncBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
+nncBits s = (<?> systemName s ++ " digits") $ digit >>= \case
+              0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                    Just _  → PC.unexpected "leading zero"
+                    Nothing → return 0 
+              r → go r
+  where go !r     = optional digit >>= \case
+                      Just d  → go ((r `shiftL` digitBits) .|. d)
+                      Nothing → return r
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
+{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
+{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-negative binary number written in the specified
+--   positional numeral system (up to /n/ digits).
+nnBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+           ⇒ s → Int → μ α
+nnBitsUpTo _ n | n <= 0 = empty
+nnBitsUpTo s n = digit >>= go (n - 1) <?> systemName s ++ " digits"
+  where go 0 !r   = optional (PC.satisfy $ isDigitIn s) >>= \case
+                      Just _  → moreThan n
+                      Nothing → return r
+        go l !r   = optional digit >>= \case
+                      Just d  → go (l - 1) ((r `shiftL` digitBits) .|. d)
+                      Nothing → return r
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word8 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word16 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word32 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word64 #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
+{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
+
+-- | Parse a non-negative binary number written in the specified
+--   positional numeral system (up to /n/ digits). Leading zeroes are not
+--   allowed.
+nncBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+            ⇒ s → Int → μ α
+nncBitsUpTo _ n | n <= 0 = empty
+nncBitsUpTo s n = (<?> systemName s ++ " digits") $ digitIn s >>= \case
+                    0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                          Just _  → PC.unexpected "leading zero"
+                          Nothing → return 0 
+                    r → go (n - 1) $ fromIntegral (r ∷ Word)
+  where go 0 !r   = optional (PC.satisfy $ isDigitIn s) >>= \case
+                      Just _  → moreThan n
+                      Nothing → return r
+        go l !r   = optional digit >>= \case
+                      Just d  → go (l - 1) ((r `shiftL` digitBits) .|. d)
+                      Nothing → return r
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word8 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word16 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word32 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word64 #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
+{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
+
+-- | Parse a non-negative binary number written in the specified
+--   positional numeral system, failing on overflow.
+nnbBits ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
+           Monad μ, CharParsing μ)
+        ⇒ s → μ α
+nnbBits s = digit >>= go <?> systemName s ++ " digits"
+  where q = maxBound `shiftR` digitBits
+        r = maxBound .&. digitMaskIn s
+        go !n = optional digit >>= \case
+                  Just d  → if n < q || (n == q && d <= r)
+                            then go ((n `shiftL` digitBits) .|. d)
+                            else fail "out of bounds"
+                  Nothing → return n
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
+{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
+{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-negative binary number written in the specified
+--   positional numeral system, failing on overflow. Leading zeroes are not
+--   allowed.
+nncbBits ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
+            Monad μ, CharParsing μ)
+         ⇒ s → μ α
+nncbBits s = (<?> systemName s ++ " digits") $ digitIn s >>= \case
+               0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                     Just _  → PC.unexpected "leading zero"
+                     Nothing → return 0
+               n → go $ fromIntegral (n ∷ Word)
+  where q = maxBound `shiftR` digitBits
+        r = maxBound .&. digitMaskIn s
+        go !n = optional digit >>= \case
+                  Just d  → if n < q || (n == q && d <= r)
+                            then go ((n `shiftL` digitBits) .|. d)
+                            else fail "out of bounds"
+                  Nothing → return n
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
+{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
+{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-positive number written in the specified positional
+--   numeral system. For example, parsing \"123\" as a decimal would produce
+--   /-123/, not /123/.
+nonPositive ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
+nonPositive s = (<?> systemName s ++ " digits") $ do
+                  r ← digitIn s
+                  go $ fromIntegral $ negate (r ∷ Int)
+  where go !r = optional digit >>= \case
+                  Just d  → go (r * radix - d)
+                  Nothing → return r
+        radix = radixIn s
+        digit = digitIn s
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
+{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
+{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
+{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-positive number written in the specified positional
+--   numeral system. Leading zeroes are not allowed.
+npCompact ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
+npCompact s = (<?> systemName s ++ " digits") $ digitIn s >>= \case
+                0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                      Just _  → PC.unexpected "leading zero"
+                      Nothing → return 0
+                r → go $ fromIntegral $ negate (r ∷ Int)
+  where go !r = optional digit >>= \case
+                  Just d  → go (r * radix - d)
+                  Nothing → return r
+        radix = radixIn s
+        digit = digitIn s
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
+{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
+{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
+{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-positive number written in the specified positional
+--   numeral system (up to /n/ digits).
+npUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → Int → μ α
+npUpTo _ n | n <= 0 = empty
+npUpTo s n = (<?> systemName s ++ " digits") $ do
+               r ← digitIn s
+               go (n - 1) $ fromIntegral $ negate (r ∷ Int)
+  where go 0 !r = optional (PC.satisfy $ isDigitIn s) >>= \case
+                    Just _  → moreThan n
+                    Nothing → return r
+        go l !r = optional digit >>= \case
+                    Just d  → go (l - 1) (r * radix - d)
+                    Nothing → return r
+        radix   = radixIn s
+        digit   = digitIn s
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int #-}
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int8 #-}
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int16 #-}
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int32 #-}
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int64 #-}
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word #-}
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word8 #-}
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word16 #-}
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word32 #-}
+{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word64 #-}
+{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
+{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
+{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → Int → μ α #-}
+{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
+{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
+{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
+
+-- | Parse a non-positive number written in the specified positional
+--   numeral system (up to /n/ digits). Leading zeroes are not allowed.
+npcUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → Int → μ α
+npcUpTo _ n | n <= 0 = empty
+npcUpTo s n = (<?> systemName s ++ " digits") $ digitIn s >>= \case
+                0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                      Just _  → PC.unexpected "leading zero"
+                      Nothing → return 0
+                r → go (n - 1) $ fromIntegral $ negate (r ∷ Int)
+  where go 0 !r = optional (PC.satisfy $ isDigitIn s) >>= \case
+                    Just _  → moreThan n
+                    Nothing → return r
+        go l !r = optional digit >>= \case
+                    Just d  → go (l - 1) (r * radix - d)
+                    Nothing → return r
+        radix   = radixIn s
+        digit   = digitIn s
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int #-}
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int8 #-}
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int16 #-}
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int32 #-}
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int64 #-}
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word #-}
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word8 #-}
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word16 #-}
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word32 #-}
+{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word64 #-}
+{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
+{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
+{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → Int → μ α #-}
+{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
+{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
+{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
+
+-- | Parse a non-positive number written in the specified positional
+--   numeral system, failing on overflow.
+npBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
+             Monad μ, CharParsing μ)
+          ⇒ s → μ α
+npBounded s = (<?> systemName s ++ " digits") $ do
+                n ← digitIn s
+                go $ fromIntegral $ negate (n ∷ Int)
+  where (q, r1) = quotRem minBound radix
+        !r      = negate r1
+        go !n   = optional digit >>= \case
+                    Just d  → if n > q || (n == q && d <= r)
+                              then go (n * radix - d)
+                              else fail "out of bounds"
+                    Nothing → return n
+        radix   = radixIn s
+        digit   = digitIn s
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
+{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
+{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
+{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-positive number written in the specified positional
+--   numeral system, failing on overflow. Leading zeroes are not allowed.
+npcBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
+              Monad μ, CharParsing μ)
+           ⇒ s → μ α
+npcBounded s = (<?> systemName s ++ " digits") $ digitIn s >>= \case
+                 0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                       Just _  → PC.unexpected "leading zero"
+                       Nothing → return 0
+                 n → go $ fromIntegral $ negate (n ∷ Int)
+  where (q, r1) = quotRem minBound radix
+        !r      = negate r1
+        go !n   = optional digit >>= \case
+                    Just d  → if n > q || (n == q && d <= r)
+                              then go (n * radix - d)
+                              else fail "out of bounds"
+                    Nothing → return n
+        radix   = radixIn s
+        digit   = digitIn s
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
+{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
+{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
+{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-positive two\'s complement binary number written in
+--   the specified positional numeral system.
+npBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
+npBits s = (<?> systemName s ++ " digits") $ do
+             r ← digit
+             go $ fromIntegral $ negate (r ∷ Int)
+  where go !r     = optional digit >>= \case
+                      Just d1 → go ((r `shiftL` digitBits) + d)
+                        where !d = fromIntegral $ negate d1
+                      Nothing → return r
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
+{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
+{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-positive two\'s complement binary number written in
+--   the specified positional numeral system (up to /n/ digits).
+npBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+           ⇒ s → Int → μ α
+npBitsUpTo _ n | n <= 0 = empty
+npBitsUpTo s n = (<?> systemName s ++ " digits") $ do
+                   r ← digit
+                   go (n - 1) $ fromIntegral $ negate (r ∷ Int)
+  where go 0 !r   = optional (PC.satisfy $ isDigitIn s) >>= \case
+                      Just _  → moreThan n
+                      Nothing → return r
+        go l !r   = optional digit >>= \case
+                      Just d1 → go (l - 1) ((r `shiftL` digitBits) + d)
+                        where !d = fromIntegral $ negate d1
+                      Nothing → return r
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word8 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word16 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word32 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word64 #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
+{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
+
+-- | Parse a non-positive two\'s complement binary number written in
+--   the specified positional numeral system. Leading zeroes are not allowed.
+npcBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
+npcBits s = (<?> systemName s ++ " digits") $ digit >>= \case
+              0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                    Just _  → PC.unexpected "leading zero"
+                    Nothing → return 0
+              r → go $ fromIntegral $ negate (r ∷ Int)
+  where go !r     = optional digit >>= \case
+                      Just d1 → go ((r `shiftL` digitBits) + d)
+                        where !d = fromIntegral $ negate d1
+                      Nothing → return r
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
+{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
+{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-positive two\'s complement binary number written in
+--   the specified positional numeral system (up to /n/ digits).
+--   Leading zeroes are not allowed.
+npcBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+            ⇒ s → Int → μ α
+npcBitsUpTo _ n | n <= 0 = empty
+npcBitsUpTo s n = (<?> systemName s ++ " digits") $ digit >>= \case
+                    0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                          Just _  → PC.unexpected "leading zero"
+                          Nothing → return 0
+                    r → go (n - 1) $ fromIntegral $ negate (r ∷ Int)
+  where go 0 !r   = optional (PC.satisfy $ isDigitIn s) >>= \case
+                      Just _  → moreThan n
+                      Nothing → return r
+        go l !r   = optional digit >>= \case
+                      Just d1 → go (l - 1) ((r `shiftL` digitBits) + d)
+                        where !d = fromIntegral $ negate d1
+                      Nothing → return r
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word8 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word16 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word32 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word64 #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
+{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
+
+-- | Parse a non-positive two\'s complement binary number written in
+--   the specified positional numeral system, failing on overflow.
+npbBits ∷ ∀ s μ α
+        . (BitSystem s, Ord α, Bounded α, Num α, Bits α,
+           Monad μ, CharParsing μ)
+        ⇒ s → μ α
+npbBits s = (<?> systemName s ++ " digits") $ do
+              n ← digit
+              go $ fromIntegral $ negate (n ∷ Int)
+  where q1 = minBound `shiftR` digitBits
+        r  = negate (lastDigitIn s (minBound ∷ α)) .&. digitMaskIn s
+        q  = if r == 0 then q1 else q1 + 1
+        go !n     = optional digit >>= \case
+                      Just d1 → if n > q || (n == q && d1 <= r)
+                                then go ((n `shiftL` digitBits) + d)
+                                else fail "out of bounds"
+                        where !d = fromIntegral $ negate d1
+                      Nothing → return n
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
+{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
+{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Parse a non-positive two\'s complement binary number written in
+--   the specified positional numeral system, failing on overflow.
+--   Leading zeroes are not allowed.
+npcbBits ∷ ∀ s μ α
+         . (BitSystem s, Ord α, Bounded α, Num α, Bits α,
+            Monad μ, CharParsing μ)
+        ⇒ s → μ α
+npcbBits s = (<?> systemName s ++ " digits") $ digit >>= \case
+               0 → optional (PC.satisfy $ isDigitIn s) >>= \case
+                     Just _  → PC.unexpected "leading zero"
+                     Nothing → return 0
+               n → go $ fromIntegral $ negate (n ∷ Int)
+  where q1 = minBound `shiftR` digitBits
+        r  = negate (lastDigitIn s (minBound ∷ α)) .&. digitMaskIn s
+        q  = if r == 0 then q1 else q1 + 1
+        go !n     = optional digit >>= \case
+                      Just d1 → if n > q || (n == q && d1 <= r)
+                                then go ((n `shiftL` digitBits) + d)
+                                else fail "out of bounds"
+                        where !d = fromIntegral $ negate d1
+                      Nothing → return n
+        digitBits = digitBitsIn s
+        digit     = digitIn s
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
+{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
+{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
+{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
+{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
+{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
+{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
+
+-- | Sign of a number.
+data Sign = NonNegative | NonPositive
+            deriving (Typeable, Eq, Show, Read)
+
+-- | Negate the supplied value if the sign is 'NonPositive' and return it
+--   as it is otherwise.
+applySign ∷ Num α ⇒ Sign → α → α
+applySign NonNegative a = a
+applySign NonPositive a = negate a
+
+-- | Optional minus sign.
+optMinus ∷ CharParsing μ ⇒ μ Sign
+optMinus  =  (pure NonPositive <* PC.char '-') <|> pure NonNegative
+         <?> "optional minus sign"
+{-# INLINE optMinus #-}
+
+-- | Optional minus or plus sign.
+optSign ∷ CharParsing μ ⇒ μ Sign
+optSign  =  (pure NonPositive <* PC.char '-')
+        <|> (pure NonNegative <* PC.char '+')
+        <|> pure NonNegative
+        <?> "optional sign"
+{-# INLINABLE optSign #-}
+
+-- | Parse a number written in the specified positional numeral system.
+--   The supplied parser is used to determine the sign of the number.
+number' ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
+        ⇒ μ Sign → s → μ α
+number' neg s = (<?> systemName s) $ neg >>= \case
+  NonNegative → nonNegative s
+  NonPositive → nonPositive s
+{-# INLINE number' #-}
+
+-- | A shorthand for 'number'' 'optMinus'.
+number ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
+number = number' optMinus
+{-# INLINE number #-}
+
+-- | Parse a number written in the specified positional numeral system.
+--   The supplied parser is used to determine the sign of the number.
+--   Leading zeroes are not allowed.
+compact' ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
+         ⇒ μ Sign → s → μ α
+compact' neg s = (<?> systemName s) $ neg >>= \case
+  NonNegative → nnCompact s
+  NonPositive → npCompact s
+{-# INLINE compact' #-}
+
+-- | A shorthand for 'compact'' 'optMinus'.
+compact ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
+compact = compact' optMinus
+{-# INLINE compact #-}
+
+-- | Parse a number written in the specified positional numeral system
+--   (up to /n/ digits). The supplied parser is used to determine the sign of
+--   the number.
+numberUpTo' ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
+            ⇒ μ Sign → s → Int → μ α
+numberUpTo' neg s n = (<?> systemName s) $ neg >>= \case
+  NonNegative → nnUpTo s n
+  NonPositive → npUpTo s n
+{-# INLINE numberUpTo' #-}
+
+-- | A shorthand for 'numberUpTo'' 'optMinus'.
+numberUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
+           ⇒ s → Int → μ α
+numberUpTo = numberUpTo' optMinus
+{-# INLINE numberUpTo #-}
+
+-- | Parse a number written in the specified positional numeral system
+--   (up to /n/ digits). The supplied parser is used to determine the sign of
+--   the number. Leading zeroes are not allowed.
+compactUpTo' ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
+             ⇒ μ Sign → s → Int → μ α
+compactUpTo' neg s n = (<?> systemName s) $ neg >>= \case
+  NonNegative → nncUpTo s n
+  NonPositive → npcUpTo s n
+{-# INLINE compactUpTo' #-}
+
+-- | A shorthand for 'compactUpTo'' 'optMinus'.
+compactUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
+           ⇒ s → Int → μ α
+compactUpTo = compactUpTo' optMinus
+{-# INLINE compactUpTo #-}
+
+-- | Parse a number written in the specified positional numeral system,
+--   failing on overflow. The supplied parser is used to determine the sign
+--   of the number.
+bounded' ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
+            Monad μ, CharParsing μ)
+         ⇒ μ Sign → s → μ α
+bounded' neg s = (<?> systemName s) $ neg >>= \case
+  NonNegative → nnBounded s
+  NonPositive → npBounded s
+{-# INLINE bounded' #-}
+
+-- | A shorthand for 'bounded'' 'optMinus'.
+bounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
+           Monad μ, CharParsing μ) ⇒ s → μ α
+bounded = bounded' optMinus
+{-# INLINE bounded #-}
+
+-- | Parse a number written in the specified positional numeral system,
+--   failing on overflow. The supplied parser is used to determine the sign
+--   of the number. Leading zeroes are not allowed.
+cBounded' ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
+             Monad μ, CharParsing μ)
+          ⇒ μ Sign → s → μ α
+cBounded' neg s = (<?> systemName s) $ neg >>= \case
+  NonNegative → nncBounded s
+  NonPositive → npcBounded s
+{-# INLINE cBounded' #-}
+
+-- | A shorthand for 'cBounded'' 'optMinus'.
+cBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
+            Monad μ, CharParsing μ) ⇒ s → μ α
+cBounded = cBounded' optMinus
+{-# INLINE cBounded #-}
+
+-- | Parse a (two\'s complement) binary number written in the specified
+--   positional numeral system. The supplied parser is used to determine
+--   the sign of the number.
+bits' ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+      ⇒ μ Sign → s → μ α
+bits' neg s = (<?> systemName s) $ neg >>= \case
+  NonNegative → nnBits s
+  NonPositive → npBits s
+{-# INLINE bits' #-}
+
+-- | A shorthand for 'bits'' 'optMinus'.
+bits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
+bits = bits' optMinus
+{-# INLINE bits #-}
+
+-- | Parse a (two\'s complement) binary number written in the specified
+--   positional numeral system. The supplied parser is used to determine
+--   the sign of the number. Leading zeroes are not allowed.
+cBits' ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+       ⇒ μ Sign → s → μ α
+cBits' neg s = (<?> systemName s) $ neg >>= \case
+  NonNegative → nncBits s
+  NonPositive → npcBits s
+{-# INLINE cBits' #-}
+
+-- | A shorthand for 'cBits'' 'optMinus'.
+cBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
+cBits = cBits' optMinus
+{-# INLINE cBits #-}
+
+-- | Parse a (two\'s complement) binary number written in the specified
+--   positional numeral system (up to /n/ digits). The supplied parser is
+--   used to determine the sign of the number.
+bitsUpTo' ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+          ⇒ μ Sign → s → Int → μ α
+bitsUpTo' neg s n = (<?> systemName s) $ neg >>= \case
+  NonNegative → nnBitsUpTo s n
+  NonPositive → npBitsUpTo s n
+{-# INLINE bitsUpTo' #-}
+
+-- | A shorthand for 'bitsUpTo'' 'optMinus'.
+bitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+         ⇒ s → Int → μ α
+bitsUpTo = bitsUpTo' optMinus
+{-# INLINE bitsUpTo #-}
+
+-- | Parse a (two\'s complement) binary number written in the specified
+--   positional numeral system (up to /n/ digits). The supplied parser is
+--   used to determine the sign of the number. Leading zeroes are not
+--   allowed.
+cBitsUpTo' ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+           ⇒ μ Sign → s → Int → μ α
+cBitsUpTo' neg s n = (<?> systemName s) $ neg >>= \case
+  NonNegative → nncBitsUpTo s n
+  NonPositive → npcBitsUpTo s n
+{-# INLINE cBitsUpTo' #-}
+
+-- | A shorthand for 'cBitsUpTo'' 'optMinus'.
+cBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
+          ⇒ s → Int → μ α
+cBitsUpTo = cBitsUpTo' optMinus
+{-# INLINE cBitsUpTo #-}
+
+-- | Parse a (two\'s complement) binary number written in the specified
+--   positional numeral system, failing on overflow. The supplied parser is
+--   used to determine the sign of the number.
+bBits' ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
+          Monad μ, CharParsing μ)
+       ⇒ μ Sign → s → μ α
+bBits' neg s = (<?> systemName s) $ neg >>= \case
+  NonNegative → nnbBits s
+  NonPositive → npbBits s
+{-# INLINE bBits' #-}
+
+-- | A shorthand for 'bBits'' 'optMinus'.
+bBits ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
+         Monad μ, CharParsing μ)
+      ⇒ s → μ α
+bBits = bBits' optMinus
+{-# INLINE bBits #-}
+
+-- | Parse a (two\'s complement) binary number written in the specified
+--   positional numeral system, failing on overflow. The supplied parser is
+--   used to determine the sign of the number. Leading zeroes are not
+--   allowed.
+cbBits' ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
+           Monad μ, CharParsing μ)
+        ⇒ μ Sign → s → μ α
+cbBits' neg s = (<?> systemName s) $ neg >>= \case
+  NonNegative → nncbBits s
+  NonPositive → npcbBits s
+{-# INLINE cbBits' #-}
+
+-- | A shorthand for 'cbBits'' 'optMinus'.
+cbBits ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
+          Monad μ, CharParsing μ)
+       ⇒ s → μ α
+cbBits = cbBits' optMinus
+{-# INLINE cbBits #-}
+
diff --git a/src/Data/Textual/Numerals.hs b/src/Data/Textual/Numerals.hs
deleted file mode 100644
--- a/src/Data/Textual/Numerals.hs
+++ /dev/null
@@ -1,1641 +0,0 @@
-{-# LANGUAGE UnicodeSyntax #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-
--- | Parsers for numbers written in positional numeral systems.
-module Data.Textual.Numerals
-  (
-  -- * Positional numeral systems
-    PositionalSystem(..)
-  , BitSystem(..)
-  , Binary(..)
-  , Octal(..)
-  , Decimal(..)
-  , Hexadecimal(..)
-  , LowHex(..)
-  , UpHex(..)
-  -- * Single digits
-  , digitIn
-  , nzDigitIn
-  , binDigit
-  , nzBinDigit
-  , octDigit
-  , nzOctDigit
-  , decDigit
-  , nzDecDigit
-  , hexDigit
-  , nzHexDigit
-  , lowHexDigit
-  , nzLowHexDigit
-  , upHexDigit
-  , nzUpHexDigit
-  -- * Numbers
-  , nonNegative
-  , nnCompact
-  , nnUpTo
-  , nncUpTo
-  , nnBounded
-  , nncBounded
-  , nnBits
-  , nncBits
-  , nnBitsUpTo
-  , nncBitsUpTo
-  , nnbBits
-  , nncbBits
-  , nonPositive
-  , npCompact
-  , npUpTo
-  , npcUpTo
-  , npBounded
-  , npcBounded
-  , npBits
-  , npcBits
-  , npBitsUpTo
-  , npcBitsUpTo
-  , npbBits
-  , npcbBits
-  , Sign(..)
-  , optMinus
-  , optSign
-  , number'
-  , number
-  , compact'
-  , compact
-  , numberUpTo'
-  , numberUpTo
-  , compactUpTo'
-  , compactUpTo
-  , bounded'
-  , bounded
-  , cBounded'
-  , cBounded
-  , bits'
-  , bits
-  , cBits'
-  , cBits
-  , bitsUpTo'
-  , bitsUpTo
-  , cBitsUpTo'
-  , cBitsUpTo
-  , bBits'
-  , bBits
-  , cbBits'
-  , cbBits
-  ) where
-
-import Data.Typeable (Typeable)
-import Data.Int
-import Data.Word
-import Data.Bits (Bits(..))
-import Control.Applicative
-import Text.Printer.Numerals (
-         PositionalSystem(..), BitSystem(..),
-         Binary(..), Octal(..), Decimal(..), Hexadecimal(..),
-         LowHex(..), UpHex(..))
-import Text.Parser.Combinators (Parsing, (<?>))
-import qualified Text.Parser.Combinators as PC
-import Text.Parser.Char (CharParsing)
-import qualified Text.Parser.Char as PC
-
--- | Parse a digit of the specified positional numeral system.
-digitIn ∷ (PositionalSystem s, Num α, CharParsing μ) ⇒ s → μ α
-digitIn s  =  unsafeFromDigitIn s <$> PC.satisfy (isDigitIn s)
-          <?> systemName s ++ " digit"
-{-# INLINE digitIn #-}
-
--- | Parse a non-zero digit of the specified positional numeral system.
-nzDigitIn ∷ (PositionalSystem s, Num α, CharParsing μ) ⇒ s → μ α
-nzDigitIn s  =  unsafeFromDigitIn s <$> PC.satisfy (isNzDigitIn s)
-            <?> "non-zero " ++ systemName s ++ " digit"
-{-# INLINE nzDigitIn #-}
-
--- | Parse a binary digit.
-binDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-binDigit = digitIn Binary
-{-# INLINE binDigit #-}
-
--- | Parse a non-zero binary digit (/'1'/).
-nzBinDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-nzBinDigit = nzDigitIn Binary
-{-# INLINE nzBinDigit #-}
-
--- | Parse a decimal digit.
-decDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-decDigit = digitIn Decimal
-{-# INLINE decDigit #-}
-
--- | Parse a non-zero decimal digit.
-nzDecDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-nzDecDigit = nzDigitIn Decimal
-{-# INLINE nzDecDigit #-}
-
--- | Parse an octal digit.
-octDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-octDigit = digitIn Octal
-{-# INLINE octDigit #-}
-
--- | Parse a non-zero octal digit.
-nzOctDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-nzOctDigit = nzDigitIn Octal
-{-# INLINE nzOctDigit #-}
-
--- | Parse a hexadecimal digit.
-hexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-hexDigit = digitIn Hexadecimal
-{-# INLINE hexDigit #-}
-
--- | Parse a non-zero hexadecimal digit.
-nzHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-nzHexDigit = nzDigitIn Hexadecimal
-{-# INLINE nzHexDigit #-}
-
--- | Parse a lower case hexadecimal digit.
-lowHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-lowHexDigit = digitIn LowHex
-{-# INLINE lowHexDigit #-}
-
--- | Parse a non-zero lower case hexadecimal digit.
-nzLowHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-nzLowHexDigit = nzDigitIn LowHex
-{-# INLINE nzLowHexDigit #-}
-
--- | Parse an upper case hexadecimal digit.
-upHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-upHexDigit = digitIn UpHex
-{-# INLINE upHexDigit #-}
-
--- | Parse a non-zero upper case hexadecimal digit.
-nzUpHexDigit ∷ (Num α, CharParsing μ) ⇒ μ α
-nzUpHexDigit = nzDigitIn UpHex
-{-# INLINE nzUpHexDigit #-}
-
--- | Parse a non-negative number written in the specified positional
---   numeral system.
-nonNegative ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
-nonNegative s = digit >>= go <?> systemName s ++ " digits"
-  where go !r = optional digit >>= \case
-                  Just d  → go (r * radix + d)
-                  Nothing → return r
-        radix = radixIn s
-        digit = digitIn s
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
-{-# SPECIALIZE nonNegative ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
-{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
-{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE nonNegative ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-negative number written in the specified positional
---   numeral system. Leading zeroes are not allowed.
-nnCompact ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
-nnCompact s = (<?> systemName s ++ " digits") $ digitIn s >>= \case
-                0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                      Just _  → PC.unexpected "leading zero"
-                      Nothing → return 0
-                r → go $ fromIntegral (r ∷ Word)
-  where go !r = optional digit >>= \case
-                  Just d  → go (r * radix + d)
-                  Nothing → return r
-        radix = radixIn s
-        digit = digitIn s
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
-{-# SPECIALIZE nnCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
-{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
-{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE nnCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
-moreThan ∷ CharParsing μ ⇒ Int → μ α
-moreThan n = PC.unexpected
-           $ "more than " ++ show n ++
-             case n of
-               1 → " digit"
-               _ → " digits"
-{-# INLINE moreThan #-}
-
--- | Parse a non-negative number written in the specified positional
---   numeral system (up to /n/ digits).
-nnUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → Int → μ α
-nnUpTo _ n | n <= 0 = empty
-nnUpTo s n = digit >>= go (n - 1) <?> systemName s ++ " digits"
-  where go 0 !r = optional (PC.satisfy $ isDigitIn s) >>= \case
-                    Just _  → moreThan n
-                    Nothing → return r
-        go l !r = optional digit >>= \case
-                    Just d  → go (l - 1) (r * radix + d)
-                    Nothing → return r
-        radix   = radixIn s
-        digit   = digitIn s
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int #-}
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int8 #-}
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int16 #-}
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int32 #-}
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int64 #-}
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word #-}
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word8 #-}
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word16 #-}
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word32 #-}
-{-# SPECIALIZE nnUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word64 #-}
-{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
-{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
-{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → Int → μ α #-}
-{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
-{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
-{-# SPECIALIZE nnUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
-
--- | Parse a non-negative number written in the specified positional
---   numeral system (up to /n/ digits). Leading zeroes are not allowed.
-nncUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → Int → μ α
-nncUpTo _ n | n <= 0 = empty
-nncUpTo s n = (<?> systemName s ++ " digits") $ digitIn s >>= \case
-                0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                      Just _  → PC.unexpected "leading zero"
-                      Nothing → return 0
-                r → go (n - 1) $ fromIntegral (r ∷ Word)
-  where go 0 !r = optional (PC.satisfy $ isDigitIn s) >>= \case
-                    Just _  → moreThan n
-                    Nothing → return r
-        go l !r = optional digit >>= \case
-                    Just d  → go (l - 1) (r * radix + d)
-                    Nothing → return r
-        radix   = radixIn s
-        digit   = digitIn s
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int #-}
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int8 #-}
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int16 #-}
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int32 #-}
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int64 #-}
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word #-}
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word8 #-}
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word16 #-}
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word32 #-}
-{-# SPECIALIZE nncUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word64 #-}
-{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
-{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
-{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → Int → μ α #-}
-{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
-{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
-{-# SPECIALIZE nncUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
-
--- | Parse a non-negative number written in the specified positional
---   numeral system, failing on overflow.
-nnBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
-             Monad μ, CharParsing μ) ⇒ s → μ α
-nnBounded s = digit >>= go <?> systemName s ++ " digits"
-  where (q, r) = quotRem maxBound radix
-        go !n  = optional digit >>= \case
-                   Just n1 → if n < q || (n == q && n1 <= r)
-                             then go (n * radix + n1)
-                             else fail "out of bounds"
-                   Nothing → return n
-        radix  = radixIn s
-        digit  = digitIn s
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
-{-# SPECIALIZE nnBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
-{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
-{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE nnBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-negative number written in the specified positional
---   numeral system, failing on overflow. Leading zeroes are not allowed.
-nncBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
-              Monad μ, CharParsing μ) ⇒ s → μ α
-nncBounded s = (<?> systemName s ++ " digits") $ digit >>= \case
-                 0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                       Just _  → PC.unexpected "leading zero"
-                       Nothing → return 0
-                 n → go n
-  where (q, r) = quotRem maxBound radix
-        go !n  = optional digit >>= \case
-                   Just d  → if n < q || (n == q && d <= r)
-                             then go (n * radix + d)
-                             else fail "out of bounds"
-                   Nothing → return n
-        radix  = radixIn s
-        digit  = digitIn s
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
-{-# SPECIALIZE nncBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
-{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
-{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE nncBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-negative binary number written in the specified
---   positional numeral system.
-nnBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
-nnBits s = digit >>= go <?> systemName s ++ " digits"
-  where go !r     = optional digit >>= \case
-                      Just d  → go ((r `shiftL` digitBits) .|. d)
-                      Nothing → return r
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
-{-# SPECIALIZE nnBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
-{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE nnBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-negative binary number written in the specified
---   positional numeral system. Leading zeroes are not allowed.
-nncBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
-nncBits s = (<?> systemName s ++ " digits") $ digit >>= \case
-              0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                    Just _  → PC.unexpected "leading zero"
-                    Nothing → return 0 
-              r → go r
-  where go !r     = optional digit >>= \case
-                      Just d  → go ((r `shiftL` digitBits) .|. d)
-                      Nothing → return r
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
-{-# SPECIALIZE nncBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
-{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE nncBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-negative binary number written in the specified
---   positional numeral system (up to /n/ digits).
-nnBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-           ⇒ s → Int → μ α
-nnBitsUpTo _ n | n <= 0 = empty
-nnBitsUpTo s n = digit >>= go (n - 1) <?> systemName s ++ " digits"
-  where go 0 !r   = optional (PC.satisfy $ isDigitIn s) >>= \case
-                      Just _  → moreThan n
-                      Nothing → return r
-        go l !r   = optional digit >>= \case
-                      Just d  → go (l - 1) ((r `shiftL` digitBits) .|. d)
-                      Nothing → return r
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word8 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word16 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word32 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word64 #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
-{-# SPECIALIZE nnBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
-
--- | Parse a non-negative binary number written in the specified
---   positional numeral system (up to /n/ digits). Leading zeroes are not
---   allowed.
-nncBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-            ⇒ s → Int → μ α
-nncBitsUpTo _ n | n <= 0 = empty
-nncBitsUpTo s n = (<?> systemName s ++ " digits") $ digitIn s >>= \case
-                    0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                          Just _  → PC.unexpected "leading zero"
-                          Nothing → return 0 
-                    r → go (n - 1) $ fromIntegral (r ∷ Word)
-  where go 0 !r   = optional (PC.satisfy $ isDigitIn s) >>= \case
-                      Just _  → moreThan n
-                      Nothing → return r
-        go l !r   = optional digit >>= \case
-                      Just d  → go (l - 1) ((r `shiftL` digitBits) .|. d)
-                      Nothing → return r
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word8 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word16 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word32 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word64 #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
-{-# SPECIALIZE nncBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
-
--- | Parse a non-negative binary number written in the specified
---   positional numeral system, failing on overflow.
-nnbBits ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
-           Monad μ, CharParsing μ)
-        ⇒ s → μ α
-nnbBits s = digit >>= go <?> systemName s ++ " digits"
-  where q = maxBound `shiftR` digitBits
-        r = maxBound .&. digitMaskIn s
-        go !n = optional digit >>= \case
-                  Just d  → if n < q || (n == q && d <= r)
-                            then go ((n `shiftL` digitBits) .|. d)
-                            else fail "out of bounds"
-                  Nothing → return n
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
-{-# SPECIALIZE nnbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
-{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE nnbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-negative binary number written in the specified
---   positional numeral system, failing on overflow. Leading zeroes are not
---   allowed.
-nncbBits ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
-            Monad μ, CharParsing μ)
-         ⇒ s → μ α
-nncbBits s = (<?> systemName s ++ " digits") $ digitIn s >>= \case
-               0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                     Just _  → PC.unexpected "leading zero"
-                     Nothing → return 0
-               n → go $ fromIntegral (n ∷ Word)
-  where q = maxBound `shiftR` digitBits
-        r = maxBound .&. digitMaskIn s
-        go !n = optional digit >>= \case
-                  Just d  → if n < q || (n == q && d <= r)
-                            then go ((n `shiftL` digitBits) .|. d)
-                            else fail "out of bounds"
-                  Nothing → return n
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
-{-# SPECIALIZE nncbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
-{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE nncbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-positive number written in the specified positional
---   numeral system. For example, parsing \"123\" as a decimal would produce
---   /-123/, not /123/.
-nonPositive ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
-nonPositive s = (<?> systemName s ++ " digits") $ do
-                  r ← digitIn s
-                  go $ fromIntegral $ negate (r ∷ Int)
-  where go !r = optional digit >>= \case
-                  Just d  → go (r * radix - d)
-                  Nothing → return r
-        radix = radixIn s
-        digit = digitIn s
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
-{-# SPECIALIZE nonPositive ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
-{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
-{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE nonPositive ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-positive number written in the specified positional
---   numeral system. Leading zeroes are not allowed.
-npCompact ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
-npCompact s = (<?> systemName s ++ " digits") $ digitIn s >>= \case
-                0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                      Just _  → PC.unexpected "leading zero"
-                      Nothing → return 0
-                r → go $ fromIntegral $ negate (r ∷ Int)
-  where go !r = optional digit >>= \case
-                  Just d  → go (r * radix - d)
-                  Nothing → return r
-        radix = radixIn s
-        digit = digitIn s
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
-{-# SPECIALIZE npCompact ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
-{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
-{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE npCompact ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-positive number written in the specified positional
---   numeral system (up to /n/ digits).
-npUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → Int → μ α
-npUpTo _ n | n <= 0 = empty
-npUpTo s n = (<?> systemName s ++ " digits") $ do
-               r ← digitIn s
-               go (n - 1) $ fromIntegral $ negate (r ∷ Int)
-  where go 0 !r = optional (PC.satisfy $ isDigitIn s) >>= \case
-                    Just _  → moreThan n
-                    Nothing → return r
-        go l !r = optional digit >>= \case
-                    Just d  → go (l - 1) (r * radix - d)
-                    Nothing → return r
-        radix   = radixIn s
-        digit   = digitIn s
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int #-}
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int8 #-}
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int16 #-}
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int32 #-}
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int64 #-}
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word #-}
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word8 #-}
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word16 #-}
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word32 #-}
-{-# SPECIALIZE npUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word64 #-}
-{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
-{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
-{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → Int → μ α #-}
-{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
-{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
-{-# SPECIALIZE npUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
-
--- | Parse a non-positive number written in the specified positional
---   numeral system (up to /n/ digits). Leading zeroes are not allowed.
-npcUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → Int → μ α
-npcUpTo _ n | n <= 0 = empty
-npcUpTo s n = (<?> systemName s ++ " digits") $ digitIn s >>= \case
-                0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                      Just _  → PC.unexpected "leading zero"
-                      Nothing → return 0
-                r → go (n - 1) $ fromIntegral $ negate (r ∷ Int)
-  where go 0 !r = optional (PC.satisfy $ isDigitIn s) >>= \case
-                    Just _  → moreThan n
-                    Nothing → return r
-        go l !r = optional digit >>= \case
-                    Just d  → go (l - 1) (r * radix - d)
-                    Nothing → return r
-        radix   = radixIn s
-        digit   = digitIn s
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int #-}
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int8 #-}
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int16 #-}
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int32 #-}
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Int64 #-}
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word #-}
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word8 #-}
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word16 #-}
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word32 #-}
-{-# SPECIALIZE npcUpTo ∷ (Monad μ, CharParsing μ) ⇒ Decimal → Int → μ Word64 #-}
-{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
-{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
-{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Decimal → Int → μ α #-}
-{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
-{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
-{-# SPECIALIZE npcUpTo ∷ (Num α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
-
--- | Parse a non-positive number written in the specified positional
---   numeral system, failing on overflow.
-npBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
-             Monad μ, CharParsing μ)
-          ⇒ s → μ α
-npBounded s = (<?> systemName s ++ " digits") $ do
-                n ← digitIn s
-                go $ fromIntegral $ negate (n ∷ Int)
-  where (q, r1) = quotRem minBound radix
-        !r      = negate r1
-        go !n   = optional digit >>= \case
-                    Just d  → if n > q || (n == q && d <= r)
-                              then go (n * radix - d)
-                              else fail "out of bounds"
-                    Nothing → return n
-        radix   = radixIn s
-        digit   = digitIn s
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
-{-# SPECIALIZE npBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
-{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
-{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE npBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-positive number written in the specified positional
---   numeral system, failing on overflow. Leading zeroes are not allowed.
-npcBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
-              Monad μ, CharParsing μ)
-           ⇒ s → μ α
-npcBounded s = (<?> systemName s ++ " digits") $ digitIn s >>= \case
-                 0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                       Just _  → PC.unexpected "leading zero"
-                       Nothing → return 0
-                 n → go $ fromIntegral $ negate (n ∷ Int)
-  where (q, r1) = quotRem minBound radix
-        !r      = negate r1
-        go !n   = optional digit >>= \case
-                    Just d  → if n > q || (n == q && d <= r)
-                              then go (n * radix - d)
-                              else fail "out of bounds"
-                    Nothing → return n
-        radix   = radixIn s
-        digit   = digitIn s
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int #-}
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int8 #-}
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int16 #-}
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int32 #-}
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Int64 #-}
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word #-}
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word8 #-}
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word16 #-}
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word32 #-}
-{-# SPECIALIZE npcBounded ∷ (Monad μ, CharParsing μ) ⇒ Decimal → μ Word64 #-}
-{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Decimal → μ α #-}
-{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE npcBounded ∷ (Ord α, Bounded α, Integral α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-positive two\'s complement binary number written in
---   the specified positional numeral system.
-npBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
-npBits s = (<?> systemName s ++ " digits") $ do
-             r ← digit
-             go $ fromIntegral $ negate (r ∷ Int)
-  where go !r     = optional digit >>= \case
-                      Just d1 → go ((r `shiftL` digitBits) + d)
-                        where !d = fromIntegral $ negate d1
-                      Nothing → return r
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
-{-# SPECIALIZE npBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
-{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE npBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-positive two\'s complement binary number written in
---   the specified positional numeral system (up to /n/ digits).
-npBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-           ⇒ s → Int → μ α
-npBitsUpTo _ n | n <= 0 = empty
-npBitsUpTo s n = (<?> systemName s ++ " digits") $ do
-                   r ← digit
-                   go (n - 1) $ fromIntegral $ negate (r ∷ Int)
-  where go 0 !r   = optional (PC.satisfy $ isDigitIn s) >>= \case
-                      Just _  → moreThan n
-                      Nothing → return r
-        go l !r   = optional digit >>= \case
-                      Just d1 → go (l - 1) ((r `shiftL` digitBits) + d)
-                        where !d = fromIntegral $ negate d1
-                      Nothing → return r
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word8 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word16 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word32 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word64 #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
-{-# SPECIALIZE npBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
-
--- | Parse a non-positive two\'s complement binary number written in
---   the specified positional numeral system. Leading zeroes are not allowed.
-npcBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
-npcBits s = (<?> systemName s ++ " digits") $ digit >>= \case
-              0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                    Just _  → PC.unexpected "leading zero"
-                    Nothing → return 0
-              r → go $ fromIntegral $ negate (r ∷ Int)
-  where go !r     = optional digit >>= \case
-                      Just d1 → go ((r `shiftL` digitBits) + d)
-                        where !d = fromIntegral $ negate d1
-                      Nothing → return r
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
-{-# SPECIALIZE npcBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
-{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE npcBits ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-positive two\'s complement binary number written in
---   the specified positional numeral system (up to /n/ digits).
---   Leading zeroes are not allowed.
-npcBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-            ⇒ s → Int → μ α
-npcBitsUpTo _ n | n <= 0 = empty
-npcBitsUpTo s n = (<?> systemName s ++ " digits") $ digit >>= \case
-                    0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                          Just _  → PC.unexpected "leading zero"
-                          Nothing → return 0
-                    r → go (n - 1) $ fromIntegral $ negate (r ∷ Int)
-  where go 0 !r   = optional (PC.satisfy $ isDigitIn s) >>= \case
-                      Just _  → moreThan n
-                      Nothing → return r
-        go l !r   = optional digit >>= \case
-                      Just d1 → go (l - 1) ((r `shiftL` digitBits) + d)
-                        where !d = fromIntegral $ negate d1
-                      Nothing → return r
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Int64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Binary → Int → μ Word64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Int64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Octal → Int → μ Word64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Int64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ Word64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Int64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ LowHex → Int → μ Word64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Int64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word8 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word16 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word32 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Monad μ, CharParsing μ) ⇒ UpHex → Int → μ Word64 #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → Int → μ α #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → Int → μ α #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → Int → μ α #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → Int → μ α #-}
-{-# SPECIALIZE npcBitsUpTo ∷ (Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → Int → μ α #-}
-
--- | Parse a non-positive two\'s complement binary number written in
---   the specified positional numeral system, failing on overflow.
-npbBits ∷ ∀ s μ α
-        . (BitSystem s, Ord α, Bounded α, Num α, Bits α,
-           Monad μ, CharParsing μ)
-        ⇒ s → μ α
-npbBits s = (<?> systemName s ++ " digits") $ do
-              n ← digit
-              go $ fromIntegral $ negate (n ∷ Int)
-  where q1 = minBound `shiftR` digitBits
-        r  = negate (lastDigitIn s (minBound ∷ α)) .&. digitMaskIn s
-        q  = if r == 0 then q1 else q1 + 1
-        go !n     = optional digit >>= \case
-                      Just d1 → if n > q || (n == q && d1 <= r)
-                                then go ((n `shiftL` digitBits) + d)
-                                else fail "out of bounds"
-                        where !d = fromIntegral $ negate d1
-                      Nothing → return n
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
-{-# SPECIALIZE npbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
-{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE npbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Parse a non-positive two\'s complement binary number written in
---   the specified positional numeral system, failing on overflow.
---   Leading zeroes are not allowed.
-npcbBits ∷ ∀ s μ α
-         . (BitSystem s, Ord α, Bounded α, Num α, Bits α,
-            Monad μ, CharParsing μ)
-        ⇒ s → μ α
-npcbBits s = (<?> systemName s ++ " digits") $ digit >>= \case
-               0 → optional (PC.satisfy $ isDigitIn s) >>= \case
-                     Just _  → PC.unexpected "leading zero"
-                     Nothing → return 0
-               n → go $ fromIntegral $ negate (n ∷ Int)
-  where q1 = minBound `shiftR` digitBits
-        r  = negate (lastDigitIn s (minBound ∷ α)) .&. digitMaskIn s
-        q  = if r == 0 then q1 else q1 + 1
-        go !n     = optional digit >>= \case
-                      Just d1 → if n > q || (n == q && d1 <= r)
-                                then go ((n `shiftL` digitBits) + d)
-                                else fail "out of bounds"
-                        where !d = fromIntegral $ negate d1
-                      Nothing → return n
-        digitBits = digitBitsIn s
-        digit     = digitIn s
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Int64 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Binary → μ Word64 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Int64 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Octal → μ Word64 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Int64 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ Hexadecimal → μ Word64 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Int64 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ LowHex → μ Word64 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Int64 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word8 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word16 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word32 #-}
-{-# SPECIALIZE npcbBits ∷ (Monad μ, CharParsing μ) ⇒ UpHex → μ Word64 #-}
-{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Binary → μ α #-}
-{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Octal → μ α #-}
-{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ Hexadecimal → μ α #-}
-{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ LowHex → μ α #-}
-{-# SPECIALIZE npcbBits ∷ (Ord α, Bounded α, Num α, Bits α, Monad μ, CharParsing μ) ⇒ UpHex → μ α #-}
-
--- | Sign of a number.
-data Sign = NonNegative | NonPositive
-            deriving (Typeable, Eq, Show, Read)
-
--- | Optional minus sign.
-optMinus ∷ CharParsing μ ⇒ μ Sign
-optMinus  =  (pure NonPositive <* PC.char '-') <|> pure NonNegative
-         <?> "optional minus sign"
-{-# INLINE optMinus #-}
-
--- | Optional minus or plus sign.
-optSign ∷ CharParsing μ ⇒ μ Sign
-optSign  =  (pure NonPositive <* PC.char '-')
-        <|> (pure NonNegative <* PC.char '+')
-        <|> pure NonNegative
-        <?> "optional sign"
-{-# INLINABLE optSign #-}
-
--- | Parse a number written in the specified positional numeral system.
---   The supplied parser is used to determine the sign of the number.
-number' ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
-        ⇒ μ Sign → s → μ α
-number' neg s = (<?> systemName s) $ neg >>= \case
-  NonNegative → nonNegative s
-  NonPositive → nonPositive s
-{-# INLINE number' #-}
-
--- | A shorthand for 'number\'' 'optMinus'.
-number ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
-number = number' optMinus
-{-# INLINE number #-}
-
--- | Parse a number written in the specified positional numeral system.
---   The supplied parser is used to determine the sign of the number.
---   Leading zeroes are not allowed.
-compact' ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
-         ⇒ μ Sign → s → μ α
-compact' neg s = (<?> systemName s) $ neg >>= \case
-  NonNegative → nnCompact s
-  NonPositive → npCompact s
-{-# INLINE compact' #-}
-
--- | A shorthand for 'compact\'' 'optMinus'.
-compact ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ) ⇒ s → μ α
-compact = compact' optMinus
-{-# INLINE compact #-}
-
--- | Parse a number written in the specified positional numeral system
---   (up to /n/ digits). The supplied parser is used to determine the sign of
---   the number.
-numberUpTo' ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
-            ⇒ μ Sign → s → Int → μ α
-numberUpTo' neg s n = (<?> systemName s) $ neg >>= \case
-  NonNegative → nnUpTo s n
-  NonPositive → npUpTo s n
-{-# INLINE numberUpTo' #-}
-
--- | A shorthand for 'numberUpTo\'' 'optMinus'.
-numberUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
-           ⇒ s → Int → μ α
-numberUpTo = numberUpTo' optMinus
-{-# INLINE numberUpTo #-}
-
--- | Parse a number written in the specified positional numeral system
---   (up to /n/ digits). The supplied parser is used to determine the sign of
---   the number. Leading zeroes are not allowed.
-compactUpTo' ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
-             ⇒ μ Sign → s → Int → μ α
-compactUpTo' neg s n = (<?> systemName s) $ neg >>= \case
-  NonNegative → nncUpTo s n
-  NonPositive → npcUpTo s n
-{-# INLINE compactUpTo' #-}
-
--- | A shorthand for 'compactUpTo\'' 'optMinus'.
-compactUpTo ∷ (PositionalSystem s, Num α, Monad μ, CharParsing μ)
-           ⇒ s → Int → μ α
-compactUpTo = compactUpTo' optMinus
-{-# INLINE compactUpTo #-}
-
--- | Parse a number written in the specified positional numeral system,
---   failing on overflow. The supplied parser is used to determine the sign
---   of the number.
-bounded' ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
-            Monad μ, CharParsing μ)
-         ⇒ μ Sign → s → μ α
-bounded' neg s = (<?> systemName s) $ neg >>= \case
-  NonNegative → nnBounded s
-  NonPositive → npBounded s
-{-# INLINE bounded' #-}
-
--- | A shorthand for 'bounded\'' 'optMinus'.
-bounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
-           Monad μ, CharParsing μ) ⇒ s → μ α
-bounded = bounded' optMinus
-{-# INLINE bounded #-}
-
--- | Parse a number written in the specified positional numeral system,
---   failing on overflow. The supplied parser is used to determine the sign
---   of the number. Leading zeroes are not allowed.
-cBounded' ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
-             Monad μ, CharParsing μ)
-          ⇒ μ Sign → s → μ α
-cBounded' neg s = (<?> systemName s) $ neg >>= \case
-  NonNegative → nncBounded s
-  NonPositive → npcBounded s
-{-# INLINE cBounded' #-}
-
--- | A shorthand for 'cBounded\'' 'optMinus'.
-cBounded ∷ (PositionalSystem s, Ord α, Bounded α, Integral α,
-            Monad μ, CharParsing μ) ⇒ s → μ α
-cBounded = cBounded' optMinus
-{-# INLINE cBounded #-}
-
--- | Parse a (two\'s complement) binary number written in the specified
---   positional numeral system. The supplied parser is used to determine
---   the sign of the number.
-bits' ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-      ⇒ μ Sign → s → μ α
-bits' neg s = (<?> systemName s) $ neg >>= \case
-  NonNegative → nnBits s
-  NonPositive → npBits s
-{-# INLINE bits' #-}
-
--- | A shorthand for 'bits\'' 'optMinus'.
-bits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
-bits = bits' optMinus
-{-# INLINE bits #-}
-
--- | Parse a (two\'s complement) binary number written in the specified
---   positional numeral system. The supplied parser is used to determine
---   the sign of the number. Leading zeroes are not allowed.
-cBits' ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-       ⇒ μ Sign → s → μ α
-cBits' neg s = (<?> systemName s) $ neg >>= \case
-  NonNegative → nncBits s
-  NonPositive → npcBits s
-{-# INLINE cBits' #-}
-
--- | A shorthand for 'cBits\'' 'optMinus'.
-cBits ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ) ⇒ s → μ α
-cBits = cBits' optMinus
-{-# INLINE cBits #-}
-
--- | Parse a (two\'s complement) binary number written in the specified
---   positional numeral system (up to /n/ digits). The supplied parser is
---   used to determine the sign of the number.
-bitsUpTo' ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-          ⇒ μ Sign → s → Int → μ α
-bitsUpTo' neg s n = (<?> systemName s) $ neg >>= \case
-  NonNegative → nnBitsUpTo s n
-  NonPositive → npBitsUpTo s n
-{-# INLINE bitsUpTo' #-}
-
--- | A shorthand for 'bitsUpTo\'' 'optMinus'.
-bitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-         ⇒ s → Int → μ α
-bitsUpTo = bitsUpTo' optMinus
-{-# INLINE bitsUpTo #-}
-
--- | Parse a (two\'s complement) binary number written in the specified
---   positional numeral system (up to /n/ digits). The supplied parser is
---   used to determine the sign of the number. Leading zeroes are not
---   allowed.
-cBitsUpTo' ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-           ⇒ μ Sign → s → Int → μ α
-cBitsUpTo' neg s n = (<?> systemName s) $ neg >>= \case
-  NonNegative → nncBitsUpTo s n
-  NonPositive → npcBitsUpTo s n
-{-# INLINE cBitsUpTo' #-}
-
--- | A shorthand for 'cBitsUpTo\'' 'optMinus'.
-cBitsUpTo ∷ (BitSystem s, Num α, Bits α, Monad μ, CharParsing μ)
-          ⇒ s → Int → μ α
-cBitsUpTo = cBitsUpTo' optMinus
-{-# INLINE cBitsUpTo #-}
-
--- | Parse a (two\'s complement) binary number written in the specified
---   positional numeral system, failing on overflow. The supplied parser is
---   used to determine the sign of the number.
-bBits' ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
-          Monad μ, CharParsing μ)
-       ⇒ μ Sign → s → μ α
-bBits' neg s = (<?> systemName s) $ neg >>= \case
-  NonNegative → nnbBits s
-  NonPositive → npbBits s
-{-# INLINE bBits' #-}
-
--- | A shorthand for 'bBits\'' 'optMinus'.
-bBits ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
-         Monad μ, CharParsing μ)
-      ⇒ s → μ α
-bBits = bBits' optMinus
-{-# INLINE bBits #-}
-
--- | Parse a (two\'s complement) binary number written in the specified
---   positional numeral system, failing on overflow. The supplied parser is
---   used to determine the sign of the number. Leading zeroes are not
---   allowed.
-cbBits' ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
-           Monad μ, CharParsing μ)
-        ⇒ μ Sign → s → μ α
-cbBits' neg s = (<?> systemName s) $ neg >>= \case
-  NonNegative → nncbBits s
-  NonPositive → npcbBits s
-{-# INLINE cbBits' #-}
-
--- | A shorthand for 'cbBits\'' 'optMinus'.
-cbBits ∷ (BitSystem s, Ord α, Bounded α, Num α, Bits α,
-          Monad μ, CharParsing μ)
-       ⇒ s → μ α
-cbBits = cbBits' optMinus
-{-# INLINE cbBits #-}
-
diff --git a/tests/Tests.hs b/tests/Tests.hs
--- a/tests/Tests.hs
+++ b/tests/Tests.hs
@@ -7,17 +7,22 @@
 import Test.Framework.Providers.QuickCheck2 (testProperty)
 import Test.QuickCheck ((==>))
 
+import Prelude hiding (print)
 import Data.Word (Word)
+import Data.Fixed (Pico)
 import Data.Proxy (Proxy)
-import Data.Textual
-import Data.Textual.Numerals
 import Control.Applicative
 import Text.Printer (StringBuilder)
 import qualified Text.Printer as TP
-import qualified Text.Printer.Numerals as TP
+import qualified Text.Printer.Integral as TP
+import qualified Text.Printer.Fractional as TP
 import Text.Parser.Combinators as PC
 import Text.Parser.Char (CharParsing)
 
+import Data.Textual
+import Data.Textual.Integral
+import Data.Textual.Fractional
+
 main = defaultMain
   [ testProperty "nonNegative Binary Int" $ \i →
       (i >= 0) ==>
@@ -277,6 +282,16 @@
       isMalformed $ parseAs anInt (cbBits Octal) "01"
   , testProperty "cbBits Octal fails on \"-01\"" $
       isMalformed $ parseAs anInt (cbBits Octal) "-01"
+  , testProperty "fraction" $ \i → 
+      parse fraction (TP.fraction i) == Parsed (i ∷ Rational)
+  , testProperty "fractional (Pico)" $ \i → 
+      parse fractional (print i) == Parsed (i ∷ Pico)
+  , testProperty "fractional (Float)" $ \i → 
+      (not (isInfinite i) && not (isNaN i)) ==>
+        parse fractional (print i) == Parsed (i ∷ Float)
+  , testProperty "fractional (Double)" $ \i → 
+      (not (isInfinite i) && not (isNaN i)) ==>
+        parse fractional (print i) == Parsed (i ∷ Double)
   ]
 
 parse ∷ (∀ μ . (Monad μ, CharParsing μ) ⇒ μ α) → StringBuilder → Parsed α
