module Data.ByteString.Read.Class
( ReadFractional(..)
, Radix(..)
) where
import Data.Word
import GHC.TypeLits.Compat
class (Fractional a, Num (Fraction a), Ord (Fraction a)) => ReadFractional a where
data Fraction a
maxValue :: proxy a -> Maybe (Fraction a)
fromFraction :: Num b => Fraction a -> b
instance ReadFractional Float where
newtype Fraction Float = FractionFloat Word32
deriving(Eq, Ord, Num)
maxValue _ = let t = 0 :: Float in Just $ fromIntegral (floatRadix t) ^ floatDigits t
fromFraction (FractionFloat a) = fromIntegral a
instance ReadFractional Double where
newtype Fraction Double = FractionDouble Word64
deriving(Eq, Ord, Num)
maxValue _ = let t = 0 :: Double in Just $ fromIntegral (floatRadix t) ^ floatDigits t
fromFraction (FractionDouble a) = fromIntegral a
instance ReadFractional Rational where
newtype Fraction Rational = WordRational Integer
deriving(Eq, Ord, Num)
maxValue _ = Nothing
fromFraction (WordRational a) = fromIntegral a
class KnownNat n => Radix n where
isDigit :: proxy n -> Word8 -> Bool
unsafeToDigit :: proxy n -> Word8 -> Word8
#define defineRadixUnder10(RADIX, MAX)\
instance Radix RADIX where;\
;\
;\
isDigit _ = \w -> 48 <= w && w <= MAX;\
unsafeToDigit _ w = w 48
defineRadixUnder10( 2, 49)
defineRadixUnder10( 3, 50)
defineRadixUnder10( 4, 51)
defineRadixUnder10( 5, 52)
defineRadixUnder10( 6, 53)
defineRadixUnder10( 7, 54)
defineRadixUnder10( 8, 55)
defineRadixUnder10( 9, 56)
defineRadixUnder10(10, 57)
#define defineRadixOver10(RADIX, MAXu, MAXl)\
instance Radix RADIX where;\
;\
;\
isDigit _ = \w -> 48 <= w && w <= 57 || 65 <= w && w <= MAXu || 97 <= w && w <= MAXl;\
unsafeToDigit _ w = if 48 <= w && w <= 57;\
then fromIntegral w 48;\
else if 65 <= w && w <= 90;\
then fromIntegral w 55;\
else fromIntegral w 87
defineRadixOver10(11, 65, 97)
defineRadixOver10(12, 66, 98)
defineRadixOver10(13, 67, 99)
defineRadixOver10(14, 68, 100)
defineRadixOver10(15, 69, 101)
defineRadixOver10(16, 70, 102)
defineRadixOver10(17, 71, 103)
defineRadixOver10(18, 72, 104)
defineRadixOver10(19, 73, 105)
defineRadixOver10(20, 74, 106)
defineRadixOver10(21, 75, 107)
defineRadixOver10(22, 76, 108)
defineRadixOver10(23, 77, 109)
defineRadixOver10(24, 78, 110)
defineRadixOver10(25, 79, 111)
defineRadixOver10(26, 80, 112)
defineRadixOver10(27, 81, 113)
defineRadixOver10(28, 82, 114)
defineRadixOver10(29, 83, 115)
defineRadixOver10(30, 84, 116)
defineRadixOver10(31, 85, 117)
defineRadixOver10(32, 86, 118)
defineRadixOver10(33, 87, 119)
defineRadixOver10(34, 88, 120)
defineRadixOver10(35, 89, 121)
defineRadixOver10(36, 90, 122)