    {-# Language DeriveDataTypeable, DeriveGeneric, Safe #-}
    {-|
    Module      : Config.Number
    Description : Scientific-notation numbers with explicit radix
    Copyright   : (c) Eric Mertens, 2019
    License     : ISC
    Maintainer  : emertens@gmail.com

    This module provides a representation of numbers in scientific
    notation.
    -}
    module Config.Number
      ( Number(..)
      , Radix(..)
      , radixToInt
      , numberToRational
      , numberToInteger
      , integerToNumber
      , rationalToNumber
      ) where

    import Data.Ratio (numerator, denominator)
    import Data.Data (Data)
    import GHC.Generics (Generic)

    -- | Numbers are represented as base, coefficient, and exponent.
    --
    -- The most convenient way to get numbers into and out of this form
    -- is to use one of: 'numberToRational', 'numberToInteger',
    -- 'rationalToNumber', or 'integerToNumber'.
    --
    -- This representation is explicit about the radix and exponent
    -- used to facilitate better pretty-printing. By using explicit
    -- exponents extremely large numbers can be represented compactly.
    -- Consider that it is easy to write `1e100000000` which would use
    -- a significant amount of memory if realized as an 'Integer'. This
    -- representation allows concerned programs to check bounds before
    -- converting to a representation like 'Integer'.
    data Number = MkNumber
      { Number -> Radix
    numberRadix       :: !Radix
      , Number -> Rational
    numberCoefficient :: !Rational
      }
      deriving (Number -> Number -> Bool
    (Number -> Number -> Bool)
    -> (Number -> Number -> Bool) -> Eq Number
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Number -> Number -> Bool
    == :: Number -> Number -> Bool
    $c/= :: Number -> Number -> Bool
    /= :: Number -> Number -> Bool
    Eq, Eq Number
    Eq Number =>
    (Number -> Number -> Ordering)
    -> (Number -> Number -> Bool)
    -> (Number -> Number -> Bool)
    -> (Number -> Number -> Bool)
    -> (Number -> Number -> Bool)
    -> (Number -> Number -> Number)
    -> (Number -> Number -> Number)
    -> Ord Number
    Number -> Number -> Bool
    Number -> Number -> Ordering
    Number -> Number -> Number
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Number -> Number -> Ordering
    compare :: Number -> Number -> Ordering
    $c< :: Number -> Number -> Bool
    < :: Number -> Number -> Bool
    $c<= :: Number -> Number -> Bool
    <= :: Number -> Number -> Bool
    $c> :: Number -> Number -> Bool
    > :: Number -> Number -> Bool
    $c>= :: Number -> Number -> Bool
    >= :: Number -> Number -> Bool
    $cmax :: Number -> Number -> Number
    max :: Number -> Number -> Number
    $cmin :: Number -> Number -> Number
    min :: Number -> Number -> Number
    Ord, ReadPrec [Number]
    ReadPrec Number
    Int -> ReadS Number
    ReadS [Number]
    (Int -> ReadS Number)
    -> ReadS [Number]
    -> ReadPrec Number
    -> ReadPrec [Number]
    -> Read Number
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Number
    readsPrec :: Int -> ReadS Number
    $creadList :: ReadS [Number]
    readList :: ReadS [Number]
    $creadPrec :: ReadPrec Number
    readPrec :: ReadPrec Number
    $creadListPrec :: ReadPrec [Number]
    readListPrec :: ReadPrec [Number]
    Read, Int -> Number -> ShowS
    [Number] -> ShowS
    Number -> String
    (Int -> Number -> ShowS)
    -> (Number -> String) -> ([Number] -> ShowS) -> Show Number
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Number -> ShowS
    showsPrec :: Int -> Number -> ShowS
    $cshow :: Number -> String
    show :: Number -> String
    $cshowList :: [Number] -> ShowS
    showList :: [Number] -> ShowS
    Show, Typeable Number
    Typeable Number =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Number -> c Number)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Number)
    -> (Number -> Constr)
    -> (Number -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Number))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Number))
    -> ((forall b. Data b => b -> b) -> Number -> Number)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Number -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Number -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Number -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Number -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Number -> m Number)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Number -> m Number)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Number -> m Number)
    -> Data Number
    Number -> Constr
    Number -> DataType
    (forall b. Data b => b -> b) -> Number -> Number
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Number -> u
    forall u. (forall d. Data d => d -> u) -> Number -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Number -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Number -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Number -> m Number
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Number -> m Number
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Number
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Number -> c Number
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Number)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Number)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Number -> c Number
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Number -> c Number
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Number
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Number
    $ctoConstr :: Number -> Constr
    toConstr :: Number -> Constr
    $cdataTypeOf :: Number -> DataType
    dataTypeOf :: Number -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Number)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Number)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Number)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Number)
    $cgmapT :: (forall b. Data b => b -> b) -> Number -> Number
    gmapT :: (forall b. Data b => b -> b) -> Number -> Number
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Number -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Number -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Number -> r
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Number -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Number -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Number -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Number -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Number -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Number -> m Number
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Number -> m Number
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Number -> m Number
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Number -> m Number
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Number -> m Number
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Number -> m Number
    Data, (forall x. Number -> Rep Number x)
    -> (forall x. Rep Number x -> Number) -> Generic Number
    forall x. Rep Number x -> Number
    forall x. Number -> Rep Number x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Number -> Rep Number x
    from :: forall x. Number -> Rep Number x
    $cto :: forall x. Rep Number x -> Number
    to :: forall x. Rep Number x -> Number
    Generic)

    -- | Radix used for a number. Some radix modes support an
    -- exponent.
    data Radix
      = Radix2           -- ^ binary, base 2
      | Radix8           -- ^ octal, base 8
      | Radix10 !Integer -- ^ decimal, base 10, exponent base 10
      | Radix16 !Integer -- ^ hexdecimal, base 16, exponent base 2
      deriving (Radix -> Radix -> Bool
    (Radix -> Radix -> Bool) -> (Radix -> Radix -> Bool) -> Eq Radix
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Radix -> Radix -> Bool
    == :: Radix -> Radix -> Bool
    $c/= :: Radix -> Radix -> Bool
    /= :: Radix -> Radix -> Bool
    Eq, Eq Radix
    Eq Radix =>
    (Radix -> Radix -> Ordering)
    -> (Radix -> Radix -> Bool)
    -> (Radix -> Radix -> Bool)
    -> (Radix -> Radix -> Bool)
    -> (Radix -> Radix -> Bool)
    -> (Radix -> Radix -> Radix)
    -> (Radix -> Radix -> Radix)
    -> Ord Radix
    Radix -> Radix -> Bool
    Radix -> Radix -> Ordering
    Radix -> Radix -> Radix
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Radix -> Radix -> Ordering
    compare :: Radix -> Radix -> Ordering
    $c< :: Radix -> Radix -> Bool
    < :: Radix -> Radix -> Bool
    $c<= :: Radix -> Radix -> Bool
    <= :: Radix -> Radix -> Bool
    $c> :: Radix -> Radix -> Bool
    > :: Radix -> Radix -> Bool
    $c>= :: Radix -> Radix -> Bool
    >= :: Radix -> Radix -> Bool
    $cmax :: Radix -> Radix -> Radix
    max :: Radix -> Radix -> Radix
    $cmin :: Radix -> Radix -> Radix
    min :: Radix -> Radix -> Radix
    Ord, ReadPrec [Radix]
    ReadPrec Radix
    Int -> ReadS Radix
    ReadS [Radix]
    (Int -> ReadS Radix)
    -> ReadS [Radix]
    -> ReadPrec Radix
    -> ReadPrec [Radix]
    -> Read Radix
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Radix
    readsPrec :: Int -> ReadS Radix
    $creadList :: ReadS [Radix]
    readList :: ReadS [Radix]
    $creadPrec :: ReadPrec Radix
    readPrec :: ReadPrec Radix
    $creadListPrec :: ReadPrec [Radix]
    readListPrec :: ReadPrec [Radix]
    Read, Int -> Radix -> ShowS
    [Radix] -> ShowS
    Radix -> String
    (Int -> Radix -> ShowS)
    -> (Radix -> String) -> ([Radix] -> ShowS) -> Show Radix
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Radix -> ShowS
    showsPrec :: Int -> Radix -> ShowS
    $cshow :: Radix -> String
    show :: Radix -> String
    $cshowList :: [Radix] -> ShowS
    showList :: [Radix] -> ShowS
    Show, Typeable Radix
    Typeable Radix =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Radix -> c Radix)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Radix)
    -> (Radix -> Constr)
    -> (Radix -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Radix))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Radix))
    -> ((forall b. Data b => b -> b) -> Radix -> Radix)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Radix -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Radix -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Radix -> m Radix)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Radix -> m Radix)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Radix -> m Radix)
    -> Data Radix
    Radix -> Constr
    Radix -> DataType
    (forall b. Data b => b -> b) -> Radix -> Radix
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Radix -> u
    forall u. (forall d. Data d => d -> u) -> Radix -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Radix -> m Radix
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Radix -> m Radix
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Radix
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Radix -> c Radix
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Radix)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Radix)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Radix -> c Radix
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Radix -> c Radix
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Radix
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Radix
    $ctoConstr :: Radix -> Constr
    toConstr :: Radix -> Constr
    $cdataTypeOf :: Radix -> DataType
    dataTypeOf :: Radix -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Radix)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Radix)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Radix)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Radix)
    $cgmapT :: (forall b. Data b => b -> b) -> Radix -> Radix
    gmapT :: (forall b. Data b => b -> b) -> Radix -> Radix
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Radix -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Radix -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Radix -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Radix -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Radix -> m Radix
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Radix -> m Radix
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Radix -> m Radix
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Radix -> m Radix
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Radix -> m Radix
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Radix -> m Radix
    Data, (forall x. Radix -> Rep Radix x)
    -> (forall x. Rep Radix x -> Radix) -> Generic Radix
    forall x. Rep Radix x -> Radix
    forall x. Radix -> Rep Radix x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Radix -> Rep Radix x
    from :: forall x. Radix -> Rep Radix x
    $cto :: forall x. Rep Radix x -> Radix
    to :: forall x. Rep Radix x -> Radix
    Generic)

    -- | Returns the radix as an integer ignoring any exponent.
    radixToInt :: Radix -> Int
    radixToInt :: Radix -> Int
    radixToInt Radix
    r =
      case Radix
    r of
        Radix2 {} ->  Int
    2
        Radix8 {} ->  Int
    8
        Radix10{} -> Int
    10
        Radix16{} -> Int
    16

    -- | Convert a number to a 'Rational'. Warning: This can use a
    -- lot of memory in the case of very large exponent parts.
    numberToRational :: Number -> Rational
    numberToRational :: Number -> Rational
    numberToRational (MkNumber Radix
    r Rational
    c) =
      case Radix
    r of
        Radix
    Radix2    -> Rational
    c
        Radix
    Radix8    -> Rational
    c
        Radix10 Integer
    e -> Rational
    c Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    * Rational
    10 Rational -> Integer -> Rational
    forall a b. (Fractional a, Integral b) => a -> b -> a
    ^^ Integer
    e
        Radix16 Integer
    e -> Rational
    c Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    *  Rational
    2 Rational -> Integer -> Rational
    forall a b. (Fractional a, Integral b) => a -> b -> a
    ^^ Integer
    e

    -- | Convert a number to a 'Integer'. Warning: This can use a
    -- lot of memory in the case of very large exponent parts.
    numberToInteger :: Number -> Maybe Integer
    numberToInteger :: Number -> Maybe Integer
    numberToInteger Number
    n
      | Rational -> Integer
    forall a. Ratio a -> a
    denominator Rational
    r Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    1 = Integer -> Maybe Integer
    forall a. a -> Maybe a
    Just (Integer -> Maybe Integer) -> Integer -> Maybe Integer
    forall a b. (a -> b) -> a -> b
    $! Rational -> Integer
    forall a. Ratio a -> a
    numerator Rational
    r
      | Bool
    otherwise          = Maybe Integer
    forall a. Maybe a
    Nothing
      where
        r :: Rational
    r = Number -> Rational
    numberToRational Number
    n

    -- | 'Integer' to a radix 10 'Number' with no exponent
    integerToNumber :: Integer -> Number
    integerToNumber :: Integer -> Number
    integerToNumber = Rational -> Number
    rationalToNumber (Rational -> Number) -> (Integer -> Rational) -> Integer -> Number
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Rational
    forall a. Num a => Integer -> a
    fromInteger

    -- | 'Rational' to a radix 10 'Number' with no exponent
    rationalToNumber :: Rational -> Number
    rationalToNumber :: Rational -> Number
    rationalToNumber = Radix -> Rational -> Number
    MkNumber (Integer -> Radix
    Radix10 Integer
    0)