{-# Language DeriveDataTypeable, DeriveGeneric #-}
{-|
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
/= :: Number -> Number -> Bool
$c/= :: Number -> Number -> Bool
== :: Number -> Number -> Bool
$c== :: 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
min :: Number -> Number -> Number
$cmin :: Number -> Number -> Number
max :: Number -> Number -> Number
$cmax :: Number -> Number -> Number
>= :: Number -> Number -> Bool
$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
compare :: Number -> Number -> Ordering
$ccompare :: Number -> Number -> Ordering
$cp1Ord :: Eq 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
readListPrec :: ReadPrec [Number]
$creadListPrec :: ReadPrec [Number]
readPrec :: ReadPrec Number
$creadPrec :: ReadPrec Number
readList :: ReadS [Number]
$creadList :: ReadS [Number]
readsPrec :: Int -> ReadS Number
$creadsPrec :: Int -> ReadS 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
showList :: [Number] -> ShowS
$cshowList :: [Number] -> ShowS
show :: Number -> String
$cshow :: Number -> String
showsPrec :: Int -> Number -> ShowS
$cshowsPrec :: Int -> Number -> ShowS
Show, Typeable Number
DataType
Constr
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 -> DataType
Number -> Constr
(forall b. Data b => b -> b) -> Number -> Number
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Number -> c Number
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c 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)
$cMkNumber :: Constr
$tNumber :: DataType
gmapMo :: (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
gmapMp :: (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
gmapM :: (forall d. Data d => d -> m d) -> Number -> m Number
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Number -> m Number
gmapQi :: Int -> (forall d. Data d => d -> u) -> Number -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Number -> u
gmapQ :: (forall d. Data d => d -> u) -> Number -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Number -> [u]
gmapQr :: (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
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Number -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Number -> r
gmapT :: (forall b. Data b => b -> b) -> Number -> Number
$cgmapT :: (forall b. Data b => b -> b) -> Number -> Number
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Number)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Number)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Number)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Number)
dataTypeOf :: Number -> DataType
$cdataTypeOf :: Number -> DataType
toConstr :: Number -> Constr
$ctoConstr :: Number -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Number
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Number
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Number -> c Number
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Number -> c Number
$cp1Data :: Typeable 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
$cto :: forall x. Rep Number x -> Number
$cfrom :: forall x. Number -> Rep Number x
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
/= :: Radix -> Radix -> Bool
$c/= :: Radix -> Radix -> Bool
== :: Radix -> Radix -> Bool
$c== :: 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
min :: Radix -> Radix -> Radix
$cmin :: Radix -> Radix -> Radix
max :: Radix -> Radix -> Radix
$cmax :: Radix -> Radix -> Radix
>= :: Radix -> Radix -> Bool
$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
compare :: Radix -> Radix -> Ordering
$ccompare :: Radix -> Radix -> Ordering
$cp1Ord :: Eq 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
readListPrec :: ReadPrec [Radix]
$creadListPrec :: ReadPrec [Radix]
readPrec :: ReadPrec Radix
$creadPrec :: ReadPrec Radix
readList :: ReadS [Radix]
$creadList :: ReadS [Radix]
readsPrec :: Int -> ReadS Radix
$creadsPrec :: Int -> ReadS 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
showList :: [Radix] -> ShowS
$cshowList :: [Radix] -> ShowS
show :: Radix -> String
$cshow :: Radix -> String
showsPrec :: Int -> Radix -> ShowS
$cshowsPrec :: Int -> Radix -> ShowS
Show, Typeable Radix
DataType
Constr
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 -> DataType
Radix -> Constr
(forall b. Data b => b -> b) -> Radix -> Radix
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Radix -> c Radix
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c 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)
$cRadix16 :: Constr
$cRadix10 :: Constr
$cRadix8 :: Constr
$cRadix2 :: Constr
$tRadix :: DataType
gmapMo :: (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
gmapMp :: (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
gmapM :: (forall d. Data d => d -> m d) -> Radix -> m Radix
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Radix -> m Radix
gmapQi :: Int -> (forall d. Data d => d -> u) -> Radix -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Radix -> u
gmapQ :: (forall d. Data d => d -> u) -> Radix -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Radix -> [u]
gmapQr :: (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
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Radix -> r
gmapT :: (forall b. Data b => b -> b) -> Radix -> Radix
$cgmapT :: (forall b. Data b => b -> b) -> Radix -> Radix
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Radix)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Radix)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Radix)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Radix)
dataTypeOf :: Radix -> DataType
$cdataTypeOf :: Radix -> DataType
toConstr :: Radix -> Constr
$ctoConstr :: Radix -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Radix
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Radix
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Radix -> c Radix
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Radix -> c Radix
$cp1Data :: Typeable 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
$cto :: forall x. Rep Radix x -> Radix
$cfrom :: forall x. Radix -> Rep Radix x
Generic)

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

-- | Convert a number to a 'Rational'. Warning: This can use a
-- lot of member in the case of very large exponent parts.
numberToRational :: Number -> Rational
numberToRational :: Number -> Rational
numberToRational (MkNumber r :: Radix
r c :: Rational
c) =
  case Radix
r of
    Radix2    -> Rational
c
    Radix8    -> Rational
c
    Radix10 e :: Integer
e -> Rational
c Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* 10 Rational -> Integer -> Rational
forall a b. (Fractional a, Integral b) => a -> b -> a
^^ Integer
e
    Radix16 e :: Integer
e -> Rational
c Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* 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 member in the case of very large exponent parts.
numberToInteger :: Number -> Maybe Integer
numberToInteger :: Number -> Maybe Integer
numberToInteger n :: Number
n
  | Rational -> Integer
forall a. Ratio a -> a
denominator Rational
r Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== 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 r :: Rational
r = (Radix -> Rational -> Number
MkNumber (Integer -> Radix
Radix10 0) Rational
r)