X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Flib%2Fstd%2FPrelNum.lhs;h=1ff4c98f28854a9c716adb3eb0e8f492256e108f;hb=111cee3f1ad93816cb828e38b38521d85c3bcebb;hp=5a835ad11991384db32ce9fdec305b89f18690de;hpb=4864e32ad1c683c7fc569d6aa5f2c605076abdbe;p=ghc-hetmet.git diff --git a/ghc/lib/std/PrelNum.lhs b/ghc/lib/std/PrelNum.lhs index 5a835ad..1ff4c98 100644 --- a/ghc/lib/std/PrelNum.lhs +++ b/ghc/lib/std/PrelNum.lhs @@ -4,123 +4,66 @@ \section[PrelNum]{Module @PrelNum@} +The class + + Num + +and the type + + Integer + + \begin{code} {-# OPTIONS -fno-implicit-prelude #-} module PrelNum where -import PrelBase -import Ix import {-# SOURCE #-} PrelErr +import PrelBase +import PrelList +import PrelEnum +import PrelShow -infixr 8 ^, ^^, ** -infixl 7 %, /, `quot`, `rem`, `div`, `mod` +infixl 7 * +infixl 6 +, - + +default () -- Double isn't available yet, + -- and we shouldn't be using defaults anyway \end{code} %********************************************************* %* * -\subsection{Standard numeric classes} +\subsection{Standard numeric class} %* * %********************************************************* \begin{code} -class (Num a, Ord a) => Real a where - toRational :: a -> Rational - -class (Real a, Enum a) => Integral a where - quot, rem, div, mod :: a -> a -> a - quotRem, divMod :: a -> a -> (a,a) - toInteger :: a -> Integer - toInt :: a -> Int -- partain: Glasgow extension - - n `quot` d = q where (q,_) = quotRem n d - n `rem` d = r where (_,r) = quotRem n d - n `div` d = q where (q,_) = divMod n d - n `mod` d = r where (_,r) = divMod n d - divMod n d = if signum r == negate (signum d) then (q-1, r+d) else qr - where qr@(q,r) = quotRem n d - -class (Num a) => Fractional a where - (/) :: a -> a -> a - recip :: a -> a - fromRational :: Rational -> a - - recip x = 1 / x - x / y = x * recip y - -class (Fractional a) => Floating a where - pi :: a - exp, log, sqrt :: a -> a - (**), logBase :: a -> a -> a - sin, cos, tan :: a -> a - asin, acos, atan :: a -> a - sinh, cosh, tanh :: a -> a - asinh, acosh, atanh :: a -> a - - x ** y = exp (log x * y) - logBase x y = log y / log x - sqrt x = x ** 0.5 - tan x = sin x / cos x - tanh x = sinh x / cosh x - -class (Real a, Fractional a) => RealFrac a where - properFraction :: (Integral b) => a -> (b,a) - truncate, round :: (Integral b) => a -> b - ceiling, floor :: (Integral b) => a -> b - - truncate x = m where (m,_) = properFraction x - - round x = let (n,r) = properFraction x - m = if r < 0 then n - 1 else n + 1 - in case signum (abs r - 0.5) of - -1 -> n - 0 -> if even n then n else m - 1 -> m - - ceiling x = if r > 0 then n + 1 else n - where (n,r) = properFraction x - - floor x = if r < 0 then n - 1 else n - where (n,r) = properFraction x - -class (RealFrac a, Floating a) => RealFloat a where - floatRadix :: a -> Integer - floatDigits :: a -> Int - floatRange :: a -> (Int,Int) - decodeFloat :: a -> (Integer,Int) - encodeFloat :: Integer -> Int -> a - exponent :: a -> Int - significand :: a -> a - scaleFloat :: Int -> a -> a - isNaN, isInfinite, isDenormalized, isNegativeZero, isIEEE - :: a -> Bool - atan2 :: a -> a -> a - - - exponent x = if m == 0 then 0 else n + floatDigits x - where (m,n) = decodeFloat x - - significand x = encodeFloat m (negate (floatDigits x)) - where (m,_) = decodeFloat x - - scaleFloat k x = encodeFloat m (n+k) - where (m,n) = decodeFloat x - - atan2 y x - | x > 0 = atan (y/x) - | x == 0 && y > 0 = pi/2 - | x < 0 && y > 0 = pi + atan (y/x) - |(x <= 0 && y < 0) || - (x < 0 && isNegativeZero y) || - (isNegativeZero x && isNegativeZero y) - = -atan2 (-y) x - | y == 0 && (x < 0 || isNegativeZero x) - = pi -- must be after the previous test on zero y - | x==0 && y==0 = y -- must be after the other double zero tests - | otherwise = x + y -- x or y is a NaN, return a NaN (via +) +class (Eq a, Show a) => Num a where + (+), (-), (*) :: a -> a -> a + negate :: a -> a + abs, signum :: a -> a + fromInteger :: Integer -> a + fromInt :: Int -> a -- partain: Glasgow extension + + x - y = x + negate y + negate x = 0 - x + fromInt (I# i#) = fromInteger (S# i#) + -- Go via the standard class-op if the + -- non-standard one ain't provided +\end{code} +A few small numeric functions + +\begin{code} +subtract :: (Num a) => a -> a -> a +{-# INLINE subtract #-} +subtract x y = y - x + +ord_0 :: Num a => a +ord_0 = fromInt (ord '0') \end{code} + %********************************************************* %* * \subsection{Instances for @Int@} @@ -128,181 +71,380 @@ class (RealFrac a, Floating a) => RealFloat a where %********************************************************* \begin{code} -instance Real Int where - toRational x = toInteger x % 1 +instance Num Int where + (+) x y = plusInt x y + (-) x y = minusInt x y + negate x = negateInt x + (*) x y = timesInt x y + abs n = if n `geInt` 0 then n else (negateInt n) + + signum n | n `ltInt` 0 = negateInt 1 + | n `eqInt` 0 = 0 + | otherwise = 1 + + fromInteger n = integer2Int n + fromInt n = n +\end{code} -instance Integral Int where - a@(I# _) `quotRem` b@(I# _) = (a `quotInt` b, a `remInt` b) + +\begin{code} +-- These can't go in PrelBase with the defn of Int, because +-- we don't have pairs defined at that time! + +quotRemInt :: Int -> Int -> (Int, Int) +a@(I# _) `quotRemInt` b@(I# _) = (a `quotInt` b, a `remInt` b) -- OK, so I made it a little stricter. Shoot me. (WDP 94/10) - -- Following chks for zero divisor are non-standard (WDP) - a `quot` b = if b /= 0 - then a `quotInt` b - else error "Prelude.Integral.quot{Int}: divide by 0" - a `rem` b = if b /= 0 - then a `remInt` b - else error "Prelude.Integral.rem{Int}: divide by 0" - - x `div` y = if x > 0 && y < 0 then quotInt (x-y-1) y - else if x < 0 && y > 0 then quotInt (x-y+1) y - else quotInt x y - x `mod` y = if x > 0 && y < 0 || x < 0 && y > 0 then - if r/=0 then r+y else 0 - else - r - where r = remInt x y - - divMod x@(I# _) y@(I# _) = (x `div` y, x `mod` y) +divModInt :: Int -> Int -> (Int, Int) +divModInt x@(I# _) y@(I# _) = (x `divInt` y, x `modInt` y) -- Stricter. Sorry if you don't like it. (WDP 94/10) +\end{code} + + +%********************************************************* +%* * +\subsection{The @Integer@ type} +%* * +%********************************************************* + +\begin{code} +data Integer + = S# Int# -- small integers + | J# Int# ByteArray# -- large integers +\end{code} ---OLD: even x = eqInt (x `mod` 2) 0 ---OLD: odd x = neInt (x `mod` 2) 0 +Convenient boxed Integer PrimOps. - toInteger (I# i) = int2Integer i -- give back a full-blown Integer - toInt x = x +\begin{code} +zeroInteger :: Integer +zeroInteger = S# 0# + +int2Integer :: Int -> Integer +{-# INLINE int2Integer #-} +int2Integer (I# i) = S# i + +integer2Int :: Integer -> Int +integer2Int (S# i) = I# i +integer2Int (J# s d) = case (integer2Int# s d) of { n# -> I# n# } + +addr2Integer :: Addr# -> Integer +{-# INLINE addr2Integer #-} +addr2Integer x = case addr2Integer# x of (# s, d #) -> J# s d +toBig (S# i) = case int2Integer# i of { (# s, d #) -> J# s d } +toBig i@(J# _ _) = i \end{code} + %********************************************************* %* * -\subsection{Instances for @Integer@} +\subsection{Dividing @Integers@} %* * %********************************************************* \begin{code} -instance Ord Integer where - (J# a1 s1 d1) <= (J# a2 s2 d2) - = (cmpInteger# a1 s1 d1 a2 s2 d2) <=# 0# +quotRemInteger :: Integer -> Integer -> (Integer, Integer) +quotRemInteger a@(S# (-2147483648#)) b = quotRemInteger (toBig a) b +quotRemInteger (S# i) (S# j) + = case quotRemInt (I# i) (I# j) of ( I# i, I# j ) -> ( S# i, S# j ) +quotRemInteger i1@(J# _ _) i2@(S# _) = quotRemInteger i1 (toBig i2) +quotRemInteger i1@(S# _) i2@(J# _ _) = quotRemInteger (toBig i1) i2 +quotRemInteger (J# s1 d1) (J# s2 d2) + = case (quotRemInteger# s1 d1 s2 d2) of + (# s3, d3, s4, d4 #) + -> (J# s3 d3, J# s4 d4) + +divModInteger a@(S# (-2147483648#)) b = divModInteger (toBig a) b +divModInteger (S# i) (S# j) + = case divModInt (I# i) (I# j) of ( I# i, I# j ) -> ( S# i, S# j) +divModInteger i1@(J# _ _) i2@(S# _) = divModInteger i1 (toBig i2) +divModInteger i1@(S# _) i2@(J# _ _) = divModInteger (toBig i1) i2 +divModInteger (J# s1 d1) (J# s2 d2) + = case (divModInteger# s1 d1 s2 d2) of + (# s3, d3, s4, d4 #) + -> (J# s3 d3, J# s4 d4) + +remInteger :: Integer -> Integer -> Integer +remInteger ia 0 + = error "Prelude.Integral.rem{Integer}: divide by 0" +remInteger a@(S# (-2147483648#)) b = remInteger (toBig a) b +remInteger (S# a) (S# b) = S# (remInt# a b) +{- Special case doesn't work, because a 1-element J# has the range + -(2^32-1) -- 2^32-1, whereas S# has the range -2^31 -- (2^31-1) +remInteger ia@(S# a) (J# sb b) + | sb ==# 1# = S# (remInt# a (word2Int# (integer2Word# sb b))) + | sb ==# -1# = S# (remInt# a (0# -# (word2Int# (integer2Word# sb b)))) + | 0# <# sb = ia + | otherwise = S# (0# -# a) +-} +remInteger ia@(S# _) ib@(J# _ _) = remInteger (toBig ia) ib +remInteger (J# sa a) (S# b) + = case int2Integer# b of { (# sb, b #) -> + case remInteger# sa a sb b of { (# sr, r #) -> + S# (sr *# (word2Int# (integer2Word# sr r))) }} +remInteger (J# sa a) (J# sb b) + = case remInteger# sa a sb b of (# sr, r #) -> J# sr r + +quotInteger :: Integer -> Integer -> Integer +quotInteger ia 0 + = error "Prelude.Integral.quot{Integer}: divide by 0" +quotInteger a@(S# (-2147483648#)) b = quotInteger (toBig a) b +quotInteger (S# a) (S# b) = S# (quotInt# a b) +{- Special case disabled, see remInteger above +quotInteger (S# a) (J# sb b) + | sb ==# 1# = S# (quotInt# a (word2Int# (integer2Word# sb b))) + | sb ==# -1# = S# (quotInt# a (0# -# (word2Int# (integer2Word# sb b)))) + | otherwise = zeroInteger +-} +quotInteger ia@(S# _) ib@(J# _ _) = quotInteger (toBig ia) ib +quotInteger (J# sa a) (S# b) + = case int2Integer# b of { (# sb, b #) -> + case quotInteger# sa a sb b of (# sq, q #) -> J# sq q } +quotInteger (J# sa a) (J# sb b) + = case quotInteger# sa a sb b of (# sg, g #) -> J# sg g +\end{code} - (J# a1 s1 d1) < (J# a2 s2 d2) - = (cmpInteger# a1 s1 d1 a2 s2 d2) <# 0# - (J# a1 s1 d1) >= (J# a2 s2 d2) - = (cmpInteger# a1 s1 d1 a2 s2 d2) >=# 0# - (J# a1 s1 d1) > (J# a2 s2 d2) - = (cmpInteger# a1 s1 d1 a2 s2 d2) ># 0# +\begin{code} +gcdInteger :: Integer -> Integer -> Integer +gcdInteger a@(S# (-2147483648#)) b = gcdInteger (toBig a) b +gcdInteger a b@(S# (-2147483648#)) = gcdInteger a (toBig b) +gcdInteger (S# a) (S# b) = S# (gcdInt# a b) +gcdInteger ia@(S# a) ib@(J# sb b) + | a ==# 0# = abs ib + | sb ==# 0# = abs ia + | otherwise = S# (gcdIntegerInt# sb b a) +gcdInteger ia@(J# sa a) ib@(S# b) + | sa ==# 0# = abs ib + | b ==# 0# = abs ia + | otherwise = S# (gcdIntegerInt# sa a b) +gcdInteger (J# sa a) (J# sb b) + = case gcdInteger# sa a sb b of (# sg, g #) -> J# sg g + +lcmInteger :: Integer -> Integer -> Integer +lcmInteger a 0 + = zeroInteger +lcmInteger 0 b + = zeroInteger +lcmInteger a b + = (divExact aa (gcdInteger aa ab)) * ab + where aa = abs a + ab = abs b + +divExact :: Integer -> Integer -> Integer +divExact a@(S# (-2147483648#)) b = divExact (toBig a) b +divExact (S# a) (S# b) = S# (quotInt# a b) +divExact (S# a) (J# sb b) + = S# (quotInt# a (sb *# (word2Int# (integer2Word# sb b)))) +divExact (J# sa a) (S# b) + = case int2Integer# b of + (# sb, b #) -> case divExactInteger# sa a sb b of (# sd, d #) -> J# sd d +divExact (J# sa a) (J# sb b) + = case divExactInteger# sa a sb b of (# sd, d #) -> J# sd d +\end{code} - x@(J# a1 s1 d1) `max` y@(J# a2 s2 d2) - = if ((cmpInteger# a1 s1 d1 a2 s2 d2) ># 0#) then x else y - x@(J# a1 s1 d1) `min` y@(J# a2 s2 d2) - = if ((cmpInteger# a1 s1 d1 a2 s2 d2) <# 0#) then x else y +%********************************************************* +%* * +\subsection{The @Integer@ instances for @Eq@, @Ord@} +%* * +%********************************************************* - compare (J# a1 s1 d1) (J# a2 s2 d2) - = case cmpInteger# a1 s1 d1 a2 s2 d2 of { res# -> +\begin{code} +instance Eq Integer where + (S# i) == (S# j) = i ==# j + (S# i) == (J# s d) = cmpIntegerInt# s d i ==# 0# + (J# s d) == (S# i) = cmpIntegerInt# s d i ==# 0# + (J# s1 d1) == (J# s2 d2) = (cmpInteger# s1 d1 s2 d2) ==# 0# + + (S# i) /= (S# j) = i /=# j + (S# i) /= (J# s d) = cmpIntegerInt# s d i /=# 0# + (J# s d) /= (S# i) = cmpIntegerInt# s d i /=# 0# + (J# s1 d1) /= (J# s2 d2) = (cmpInteger# s1 d1 s2 d2) /=# 0# + +------------------------------------------------------------------------ +instance Ord Integer where + (S# i) <= (S# j) = i <=# j + (J# s d) <= (S# i) = cmpIntegerInt# s d i <=# 0# + (S# i) <= (J# s d) = cmpIntegerInt# s d i >=# 0# + (J# s1 d1) <= (J# s2 d2) = (cmpInteger# s1 d1 s2 d2) <=# 0# + + (S# i) > (S# j) = i ># j + (J# s d) > (S# i) = cmpIntegerInt# s d i ># 0# + (S# i) > (J# s d) = cmpIntegerInt# s d i <# 0# + (J# s1 d1) > (J# s2 d2) = (cmpInteger# s1 d1 s2 d2) ># 0# + + (S# i) < (S# j) = i <# j + (J# s d) < (S# i) = cmpIntegerInt# s d i <# 0# + (S# i) < (J# s d) = cmpIntegerInt# s d i ># 0# + (J# s1 d1) < (J# s2 d2) = (cmpInteger# s1 d1 s2 d2) <# 0# + + (S# i) >= (S# j) = i >=# j + (J# s d) >= (S# i) = cmpIntegerInt# s d i >=# 0# + (S# i) >= (J# s d) = cmpIntegerInt# s d i <=# 0# + (J# s1 d1) >= (J# s2 d2) = (cmpInteger# s1 d1 s2 d2) >=# 0# + + compare (S# i) (S# j) + | i ==# j = EQ + | i <=# j = LT + | otherwise = GT + compare (J# s d) (S# i) + = case cmpIntegerInt# s d i of { res# -> if res# <# 0# then LT else if res# ># 0# then GT else EQ } + compare (S# i) (J# s d) + = case cmpIntegerInt# s d i of { res# -> + if res# ># 0# then LT else + if res# <# 0# then GT else EQ + } + compare (J# s1 d1) (J# s2 d2) + = case cmpInteger# s1 d1 s2 d2 of { res# -> + if res# <# 0# then LT else + if res# ># 0# then GT else EQ + } +\end{code} -instance Num Integer where - (+) (J# a1 s1 d1) (J# a2 s2 d2) - = case plusInteger# a1 s1 d1 a2 s2 d2 of (# a, s, d #) -> J# a s d - - (-) (J# a1 s1 d1) (J# a2 s2 d2) - = case minusInteger# a1 s1 d1 a2 s2 d2 of (# a, s, d #) -> J# a s d - negate (J# a s d) - = case negateInteger# a s d of (# a1, s1, d1 #) -> J# a1 s1 d1 +%********************************************************* +%* * +\subsection{The @Integer@ instances for @Num@} +%* * +%********************************************************* - (*) (J# a1 s1 d1) (J# a2 s2 d2) - = case timesInteger# a1 s1 d1 a2 s2 d2 of (# a, s, d #) -> J# a s d +\begin{code} +instance Num Integer where + (+) i1@(S# i) i2@(S# j) + = case addIntC# i j of { (# r, c #) -> + if c ==# 0# then S# r + else toBig i1 + toBig i2 } + (+) i1@(J# _ _) i2@(S# _) = i1 + toBig i2 + (+) i1@(S# _) i2@(J# _ _) = toBig i1 + i2 + (+) (J# s1 d1) (J# s2 d2) + = case plusInteger# s1 d1 s2 d2 of (# s, d #) -> J# s d + + (-) i1@(S# i) i2@(S# j) + = case subIntC# i j of { (# r, c #) -> + if c ==# 0# then S# r + else toBig i1 - toBig i2 } + (-) i1@(J# _ _) i2@(S# _) = i1 - toBig i2 + (-) i1@(S# _) i2@(J# _ _) = toBig i1 - i2 + (-) (J# s1 d1) (J# s2 d2) + = case minusInteger# s1 d1 s2 d2 of (# s, d #) -> J# s d + + (*) i1@(S# i) i2@(S# j) + = case mulIntC# i j of { (# r, c #) -> + if c ==# 0# then S# r + else toBig i1 * toBig i2 } + (*) i1@(J# _ _) i2@(S# _) = i1 * toBig i2 + (*) i1@(S# _) i2@(J# _ _) = toBig i1 * i2 + (*) (J# s1 d1) (J# s2 d2) + = case timesInteger# s1 d1 s2 d2 of (# s, d #) -> J# s d + + negate (S# (-2147483648#)) = 2147483648 + negate (S# i) = S# (negateInt# i) + negate (J# s d) = J# (negateInt# s) d -- ORIG: abs n = if n >= 0 then n else -n - abs n@(J# a1 s1 d1) - = case 0 of { J# a2 s2 d2 -> - if (cmpInteger# a1 s1 d1 a2 s2 d2) >=# 0# - then n - else case negateInteger# a1 s1 d1 of (# a, s, d #) -> J# a s d - } - - signum (J# a1 s1 d1) - = case 0 of { J# a2 s2 d2 -> - let - cmp = cmpInteger# a1 s1 d1 a2 s2 d2 + abs (S# (-2147483648#)) = 2147483648 + abs (S# i) = case abs (I# i) of I# j -> S# j + abs n@(J# s d) = if (s >=# 0#) then n else J# (negateInt# s) d + + signum (S# i) = case signum (I# i) of I# j -> S# j + signum (J# s d) + = let + cmp = cmpIntegerInt# s d 0# in - if cmp ># 0# then 1 - else if cmp ==# 0# then 0 - else (negate 1) - } + if cmp ># 0# then S# 1# + else if cmp ==# 0# then S# 0# + else S# (negateInt# 1#) fromInteger x = x - fromInt (I# i) = int2Integer i - -instance Real Integer where - toRational x = x % 1 - -instance Integral Integer where - quotRem (J# a1 s1 d1) (J# a2 s2 d2) - = case (quotRemInteger# a1 s1 d1 a2 s2 d2) of - (# a3, s3, d3, a4, s4, d4 #) - -> (J# a3 s3 d3, J# a4 s4 d4) + fromInt (I# i) = S# i +\end{code} -{- USING THE UNDERLYING "GMP" CODE IS DUBIOUS FOR NOW: - divMod (J# a1 s1 d1) (J# a2 s2 d2) - = case (divModInteger# a1 s1 d1 a2 s2 d2) of - Return2GMPs a3 s3 d3 a4 s4 d4 - -> (J# a3 s3 d3, J# a4 s4 d4) --} - toInteger n = n - toInt (J# a s d) = case (integer2Int# a s d) of { n# -> I# n# } - - -- the rest are identical to the report default methods; - -- you get slightly better code if you let the compiler - -- see them right here: - n `quot` d = if d /= 0 then q else - error "Prelude.Integral.quot{Integer}: divide by 0" - where (q,_) = quotRem n d - n `rem` d = if d /= 0 then r else - error "Prelude.Integral.rem{Integer}: divide by 0" - where (_,r) = quotRem n d - n `div` d = q where (q,_) = divMod n d - n `mod` d = r where (_,r) = divMod n d - - divMod n d = case (quotRem n d) of { qr@(q,r) -> - if signum r == negate (signum d) then (q - 1, r+d) else qr } - -- Case-ified by WDP 94/10 +%********************************************************* +%* * +\subsection{The @Integer@ instance for @Enum@} +%* * +%********************************************************* +\begin{code} instance Enum Integer where succ x = x + 1 pred x = x - 1 - toEnum n = toInteger n - fromEnum n = toInt n - enumFrom n = n : enumFrom (n + 1) - enumFromThen e1 e2 = en' e1 (e2 - e1) - where en' a b = a : en' (a + b) b - enumFromTo n m - | n <= m = takeWhile (<= m) (enumFrom n) - | otherwise = takeWhile (>= m) (enumFromThen n (n-1)) - enumFromThenTo n m p = takeWhile pred (enumFromThen n m) - where - pred | m >= n = (<= p) - | otherwise = (>= p) + toEnum n = int2Integer n + fromEnum n = integer2Int n + + {-# INLINE enumFrom #-} + {-# INLINE enumFromThen #-} + {-# INLINE enumFromTo #-} + {-# INLINE enumFromThenTo #-} + enumFrom x = efdInteger x 1 + enumFromThen x y = efdInteger x (y-x) + enumFromTo x lim = efdtInteger x 1 lim + enumFromThenTo x y lim = efdtInteger x (y-x) lim + + +efdInteger = enumDeltaIntegerList +efdtInteger = enumDeltaToIntegerList + +{-# RULES +"efdInteger" forall x y. efdInteger x y = build (\c _ -> enumDeltaIntegerFB c x y) +"efdtInteger" forall x y l.efdtInteger x y l = build (\c n -> enumDeltaToIntegerFB c n x y l) +"enumDeltaInteger" enumDeltaIntegerFB (:) = enumDeltaIntegerList +"enumDeltaToInteger" enumDeltaToIntegerFB (:) [] = enumDeltaToIntegerList + #-} + +enumDeltaIntegerFB :: (Integer -> b -> b) -> Integer -> Integer -> b +enumDeltaIntegerFB c x d = x `c` enumDeltaIntegerFB c (x+d) d + +enumDeltaIntegerList :: Integer -> Integer -> [Integer] +enumDeltaIntegerList x d = x : enumDeltaIntegerList (x+d) d + +enumDeltaToIntegerFB c n x delta lim + | delta >= 0 = up_fb c n x delta lim + | otherwise = dn_fb c n x delta lim + +enumDeltaToIntegerList x delta lim + | delta >= 0 = up_list x delta lim + | otherwise = dn_list x delta lim + +up_fb c n x delta lim = go (x::Integer) + where + go x | x > lim = n + | otherwise = x `c` go (x+delta) +dn_fb c n x delta lim = go (x::Integer) + where + go x | x < lim = n + | otherwise = x `c` go (x+delta) + +up_list x delta lim = go (x::Integer) + where + go x | x > lim = [] + | otherwise = x : go (x+delta) +dn_list x delta lim = go (x::Integer) + where + go x | x < lim = [] + | otherwise = x : go (x+delta) -instance Show Integer where - showsPrec x = showSignedInteger x - showList = showList__ (showsPrec 0) +\end{code} -instance Ix Integer where - range (m,n) = [m..n] - index b@(m,_) i - | inRange b i = fromInteger (i - m) - | otherwise = indexIntegerError i b - inRange (m,n) i = m <= i && i <= n +%********************************************************* +%* * +\subsection{The @Integer@ instances for @Show@} +%* * +%********************************************************* --- Sigh, really want to use helper function in Ix, but --- module deps. are too painful. -{-# NOINLINE indexIntegerError #-} -indexIntegerError :: Integer -> (Integer,Integer) -> a -indexIntegerError i rng - = error (showString "Ix{Integer}.index: Index " . - showParen True (showsPrec 0 i) . - showString " out of range " $ - showParen True (showsPrec 0 rng) "") +\begin{code} +instance Show Integer where + showsPrec x = showSignedInteger x + showList = showList__ (showsPrec 0) showSignedInteger :: Int -> Integer -> ShowS showSignedInteger p n r @@ -317,91 +459,7 @@ jtos i rs jtos' :: Integer -> String -> String jtos' n cs | n < 10 = chr (fromInteger n + (ord_0::Int)) : cs - | otherwise = jtos' q (chr (toInt r + (ord_0::Int)) : cs) + | otherwise = jtos' q (chr (integer2Int r + (ord_0::Int)) : cs) where - (q,r) = n `quotRem` 10 + (q,r) = n `quotRemInteger` 10 \end{code} - -%********************************************************* -%* * -\subsection{The @Ratio@ and @Rational@ types} -%* * -%********************************************************* - -\begin{code} -data (Integral a) => Ratio a = !a :% !a deriving (Eq) -type Rational = Ratio Integer - -{-# SPECIALISE (%) :: Integer -> Integer -> Rational #-} -(%) :: (Integral a) => a -> a -> Ratio a -numerator, denominator :: (Integral a) => Ratio a -> a -\end{code} - -\tr{reduce} is a subsidiary function used only in this module . -It normalises a ratio by dividing both numerator and denominator by -their greatest common divisor. - -\begin{code} -reduce :: (Integral a) => a -> a -> Ratio a -reduce _ 0 = error "Ratio.%: zero denominator" -reduce x y = (x `quot` d) :% (y `quot` d) - where d = gcd x y -\end{code} - -\begin{code} -x % y = reduce (x * signum y) (abs y) - -numerator (x :% _) = x -denominator (_ :% y) = y - -\end{code} - -%********************************************************* -%* * -\subsection{Overloaded numeric functions} -%* * -%********************************************************* - -\begin{code} -even, odd :: (Integral a) => a -> Bool -even n = n `rem` 2 == 0 -odd = not . even - -{-# SPECIALISE gcd :: - Int -> Int -> Int, - Integer -> Integer -> Integer #-} -gcd :: (Integral a) => a -> a -> a -gcd 0 0 = error "Prelude.gcd: gcd 0 0 is undefined" -gcd x y = gcd' (abs x) (abs y) - where gcd' a 0 = a - gcd' a b = gcd' b (a `rem` b) - -{-# SPECIALISE lcm :: - Int -> Int -> Int, - Integer -> Integer -> Integer #-} -lcm :: (Integral a) => a -> a -> a -lcm _ 0 = 0 -lcm 0 _ = 0 -lcm x y = abs ((x `quot` (gcd x y)) * y) - -{-# SPECIALISE (^) :: - Integer -> Integer -> Integer, - Integer -> Int -> Integer, - Int -> Int -> Int #-} -(^) :: (Num a, Integral b) => a -> b -> a -_ ^ 0 = 1 -x ^ n | n > 0 = f x (n-1) x - where f _ 0 y = y - f a d y = g a d where - g b i | even i = g (b*b) (i `quot` 2) - | otherwise = f b (i-1) (b*y) -_ ^ _ = error "Prelude.^: negative exponent" - -{- SPECIALISE (^^) :: - Double -> Int -> Double, - Rational -> Int -> Rational #-} -(^^) :: (Fractional a, Integral b) => a -> b -> a -x ^^ n = if n >= 0 then x^n else recip (x^(negate n)) - -\end{code} -