{-# LANGUAGE CPP, NoImplicitPrelude #-}
module Numeric.Compat (
module Base
, showBin
, showFFloatAlt
, showGFloatAlt
, showHFloat
, readBin
) where
import Numeric as Base
#if !(MIN_VERSION_base(4,16,0))
import Data.Char (intToDigit)
import Prelude
import Text.ParserCombinators.ReadP (readP_to_S)
import qualified Text.Read.Lex.Compat as L
#endif
#if !(MIN_VERSION_base(4,11,0))
showHFloat :: RealFloat a => a -> ShowS
showHFloat = showString . fmt
where
fmt x
| isNaN x = "NaN"
| isInfinite x = (if x < 0 then "-" else "") ++ "Infinity"
| x < 0 || isNegativeZero x = '-' : cvt (-x)
| otherwise = cvt x
cvt x
| x == 0 = "0x0p+0"
| otherwise =
case floatToDigits 2 x of
r@([], _) -> error $ "Impossible happened: showHFloat: " ++ show r
(d:ds, e) -> "0x" ++ show d ++ frac ds ++ "p" ++ show (e-1)
frac digits
| allZ digits = ""
| otherwise = "." ++ hex digits
where
hex ds =
case ds of
[] -> ""
[a] -> hexDigit a 0 0 0 ""
[a,b] -> hexDigit a b 0 0 ""
[a,b,c] -> hexDigit a b c 0 ""
a : b : c : d : r -> hexDigit a b c d (hex r)
hexDigit a b c d = showHex (8*a + 4*b + 2*c + d)
allZ xs = case xs of
x : more -> x == 0 && allZ more
[] -> True
#endif
#if !(MIN_VERSION_base(4,16,0))
readBin :: (Eq a, Num a) => ReadS a
readBin = readP_to_S L.readBinP
showBin :: (Integral a, Show a) => a -> ShowS
showBin = showIntAtBase 2 intToDigit
#endif