{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude, MagicHash #-}
module Numeric (
showSigned,
showIntAtBase,
showInt,
showHex,
showOct,
showEFloat,
showFFloat,
showGFloat,
showFFloatAlt,
showGFloatAlt,
showFloat,
floatToDigits,
readSigned,
readInt,
readDec,
readOct,
readHex,
readFloat,
lexDigits,
fromRat,
) where
import GHC.Base
import GHC.Read
import GHC.Real
import GHC.Float
import GHC.Num
import GHC.Show
import Data.Maybe
import Text.ParserCombinators.ReadP( ReadP, readP_to_S, pfail )
import qualified Text.Read.Lex as L
readInt :: Num a
=> a
-> (Char -> Bool)
-> (Char -> Int)
-> ReadS a
readInt base isDigit valDigit = readP_to_S (L.readIntP base isDigit valDigit)
readOct :: (Eq a, Num a) => ReadS a
readOct = readP_to_S L.readOctP
readDec :: (Eq a, Num a) => ReadS a
readDec = readP_to_S L.readDecP
readHex :: (Eq a, Num a) => ReadS a
readHex = readP_to_S L.readHexP
readFloat :: RealFrac a => ReadS a
readFloat = readP_to_S readFloatP
readFloatP :: RealFrac a => ReadP a
readFloatP =
do tok <- L.lex
case tok of
L.Number n -> return $ fromRational $ L.numberToRational n
_ -> pfail
readSigned :: (Real a) => ReadS a -> ReadS a
readSigned readPos = readParen False read'
where read' r = read'' r ++
(do
("-",s) <- lex r
(x,t) <- read'' s
return (-x,t))
read'' r = do
(str,s) <- lex r
(n,"") <- readPos str
return (n,s)
showInt :: Integral a => a -> ShowS
showInt n0 cs0
| n0 < 0 = error "Numeric.showInt: can't show negative numbers"
| otherwise = go n0 cs0
where
go n cs
| n < 10 = case unsafeChr (ord '0' + fromIntegral n) of
c@(C# _) -> c:cs
| otherwise = case unsafeChr (ord '0' + fromIntegral r) of
c@(C# _) -> go q (c:cs)
where
(q,r) = n `quotRem` 10
{-# SPECIALIZE showEFloat ::
Maybe Int -> Float -> ShowS,
Maybe Int -> Double -> ShowS #-}
{-# SPECIALIZE showFFloat ::
Maybe Int -> Float -> ShowS,
Maybe Int -> Double -> ShowS #-}
{-# SPECIALIZE showGFloat ::
Maybe Int -> Float -> ShowS,
Maybe Int -> Double -> ShowS #-}
showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
showEFloat d x = showString (formatRealFloat FFExponent d x)
showFFloat d x = showString (formatRealFloat FFFixed d x)
showGFloat d x = showString (formatRealFloat FFGeneric d x)
showFFloatAlt :: (RealFloat a) => Maybe Int -> a -> ShowS
showGFloatAlt :: (RealFloat a) => Maybe Int -> a -> ShowS
showFFloatAlt d x = showString (formatRealFloatAlt FFFixed d True x)
showGFloatAlt d x = showString (formatRealFloatAlt FFGeneric d True x)
showIntAtBase :: (Integral a, Show a) => a -> (Int -> Char) -> a -> ShowS
showIntAtBase base toChr n0 r0
| base <= 1 = error ("Numeric.showIntAtBase: applied to unsupported base " ++ show base)
| n0 < 0 = error ("Numeric.showIntAtBase: applied to negative number " ++ show n0)
| otherwise = showIt (quotRem n0 base) r0
where
showIt (n,d) r = seq c $
case n of
0 -> r'
_ -> showIt (quotRem n base) r'
where
c = toChr (fromIntegral d)
r' = c : r
showHex :: (Integral a,Show a) => a -> ShowS
showHex = showIntAtBase 16 intToDigit
showOct :: (Integral a, Show a) => a -> ShowS
showOct = showIntAtBase 8 intToDigit