bde290df10ee1a196fcc72a1206b3e48192cb67c
1 {-# OPTIONS -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module : Numeric
5 -- Copyright : (c) The University of Glasgow 2002
7 --
9 -- Stability : provisional
10 -- Portability : portable
11 --
12 -- Odds and ends, mostly functions for reading and showing
13 -- RealFloat-like kind of values.
14 --
15 -----------------------------------------------------------------------------
17 module Numeric (
19 fromRat, -- :: (RealFloat a) => Rational -> a
20 showSigned, -- :: (Real a) => (a -> ShowS) -> Int -> a -> ShowS
23 readInt, -- :: (Integral a) => a -> (Char -> Bool)
24 -- -> (Char -> Int) -> ReadS a
29 showInt, -- :: Integral a => a -> ShowS
30 showIntAtBase, -- :: Integral a => a -> (a -> Char) -> a -> ShowS
31 showHex, -- :: Integral a => a -> ShowS
32 showOct, -- :: Integral a => a -> ShowS
34 showEFloat, -- :: (RealFloat a) => Maybe Int -> a -> ShowS
35 showFFloat, -- :: (RealFloat a) => Maybe Int -> a -> ShowS
36 showGFloat, -- :: (RealFloat a) => Maybe Int -> a -> ShowS
37 showFloat, -- :: (RealFloat a) => a -> ShowS
40 floatToDigits, -- :: (RealFloat a) => Integer -> a -> ([Int], Int)
41 lexDigits, -- :: ReadS String
43 ) where
45 import Data.Char
48 import GHC.Base
50 import GHC.Real
51 import GHC.Float
52 import GHC.Num
53 import GHC.Show
54 import Data.Maybe
56 import qualified Text.Read.Lex as L
57 #endif
59 #ifdef __HUGS__
60 import Hugs.Prelude
61 import Hugs.Numeric
62 #endif
65 -- -----------------------------------------------------------------------------
68 readInt :: Num a => a -> (Char -> Bool) -> (Char -> Int) -> ReadS a
81 do tok <- L.lex
82 case tok of
83 L.Rat y -> return (fromRational y)
84 L.Int i -> return (fromInteger i)
85 other -> pfail
87 -- It's turgid to have readSigned work using list comprehensions,
89 -- With a bit of luck no one will use it.
93 (do
94 ("-",s) <- lex r
96 return (-x,t))
98 (str,s) <- lex r
100 return (n,s)
102 -- -----------------------------------------------------------------------------
103 -- Showing
105 showInt :: Integral a => a -> ShowS
106 showInt n cs
107 | n < 0 = error "Numeric.showInt: can't show negative numbers"
108 | otherwise = go n cs
109 where
110 go n cs
111 | n < 10 = case unsafeChr (ord '0' + fromIntegral n) of
112 c@(C# _) -> c:cs
113 | otherwise = case unsafeChr (ord '0' + fromIntegral r) of
114 c@(C# _) -> go q (c:cs)
115 where
116 (q,r) = n `quotRem` 10
118 -- Controlling the format and precision of floats. The code that
119 -- implements the formatting itself is in @PrelNum@ to avoid
120 -- mutual module deps.
122 {-# SPECIALIZE showEFloat ::
123 Maybe Int -> Float -> ShowS,
124 Maybe Int -> Double -> ShowS #-}
125 {-# SPECIALIZE showFFloat ::
126 Maybe Int -> Float -> ShowS,
127 Maybe Int -> Double -> ShowS #-}
128 {-# SPECIALIZE showGFloat ::
129 Maybe Int -> Float -> ShowS,
130 Maybe Int -> Double -> ShowS #-}
132 showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
133 showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
134 showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
136 showEFloat d x = showString (formatRealFloat FFExponent d x)
137 showFFloat d x = showString (formatRealFloat FFFixed d x)
138 showGFloat d x = showString (formatRealFloat FFGeneric d x)
141 -- ---------------------------------------------------------------------------
142 -- Integer printing functions
144 showIntAtBase :: Integral a => a -> (Int -> Char) -> a -> ShowS
145 showIntAtBase base toChr n r
146 | base <= 1 = error ("Numeric.showIntAtBase: applied to unsupported base " ++ show base)
147 | n < 0 = error ("Numeric.showIntAtBase: applied to negative number " ++ show n)
148 | otherwise = showIt (quotRem n base) r
149 where
150 showIt (n,d) r = seq c \$ -- stricter than necessary
151 case n of
152 0 -> r'
153 _ -> showIt (quotRem n base) r'
154 where
155 c = toChr (fromIntegral d)
156 r' = c : r
158 showHex, showOct :: Integral a => a -> ShowS
159 showHex = showIntAtBase 16 intToDigit
160 showOct = showIntAtBase 8 intToDigit