\begin{code}
-{-# OPTIONS_GHC -fno-implicit-prelude #-}
+{-# OPTIONS_GHC -XNoImplicitPrelude #-}
+{-# OPTIONS_HADDOCK hide #-}
-----------------------------------------------------------------------------
-- |
-- Module : GHC.Real
--- Copyright : (c) The FFI Task Force, 1994-2002
+-- Copyright : (c) The University of Glasgow, 1994-2002
-- License : see libraries/base/LICENSE
--
-- Maintainer : cvs-ghc@haskell.org
--
-----------------------------------------------------------------------------
+-- #hide
module GHC.Real where
-import {-# SOURCE #-} GHC.Err
import GHC.Base
import GHC.Num
import GHC.List
import GHC.Enum
import GHC.Show
+import GHC.Err
infixr 8 ^, ^^
infixl 7 /, `quot`, `rem`, `div`, `mod`
infixl 7 %
-default () -- Double isn't available yet,
- -- and we shouldn't be using defaults anyway
+default () -- Double isn't available yet,
+ -- and we shouldn't be using defaults anyway
\end{code}
%*********************************************************
-%* *
+%* *
\subsection{The @Ratio@ and @Rational@ types}
-%* *
+%* *
%*********************************************************
\begin{code}
-- | Rational numbers, with numerator and denominator of some 'Integral' type.
-data (Integral a) => Ratio a = !a :% !a deriving (Eq)
+data (Integral a) => Ratio a = !a :% !a deriving (Eq)
-- | Arbitrary-precision rational numbers, represented as a ratio of
-- two 'Integer' values. A rational number may be constructed using
-- the '%' operator.
-type Rational = Ratio Integer
+type Rational = Ratio Integer
ratioPrec, ratioPrec1 :: Int
-ratioPrec = 7 -- Precedence of ':%' constructor
+ratioPrec = 7 -- Precedence of ':%' constructor
ratioPrec1 = ratioPrec + 1
infinity, notANumber :: Rational
\begin{code}
-- | Forms the ratio of two integral numbers.
{-# SPECIALISE (%) :: Integer -> Integer -> Rational #-}
-(%) :: (Integral a) => a -> a -> Ratio a
+(%) :: (Integral a) => a -> a -> Ratio a
-- | Extract the numerator of the ratio in reduced form:
-- the numerator and denominator have no common factor and the denominator
-- is positive.
-numerator :: (Integral a) => Ratio a -> a
+numerator :: (Integral a) => Ratio a -> a
-- | Extract the denominator of the ratio in reduced form:
-- the numerator and denominator have no common factor and the denominator
-- is positive.
-denominator :: (Integral a) => Ratio a -> a
+denominator :: (Integral a) => Ratio a -> a
\end{code}
\tr{reduce} is a subsidiary function used only in this module .
\begin{code}
reduce :: (Integral a) => a -> a -> Ratio a
{-# SPECIALISE reduce :: Integer -> Integer -> Rational #-}
-reduce _ 0 = error "Ratio.%: zero denominator"
-reduce x y = (x `quot` d) :% (y `quot` d)
- where d = gcd x y
+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)
+x % y = reduce (x * signum y) (abs y)
-numerator (x :% _) = x
-denominator (_ :% y) = y
+numerator (x :% _) = x
+denominator (_ :% y) = y
\end{code}
%*********************************************************
-%* *
+%* *
\subsection{Standard numeric classes}
-%* *
+%* *
%*********************************************************
\begin{code}
class (Num a, Ord a) => Real a where
-- | the rational equivalent of its real argument with full precision
- toRational :: a -> Rational
+ toRational :: a -> Rational
-- | Integral numbers, supporting integer division.
--
-- Minimal complete definition: 'quotRem' and 'toInteger'
class (Real a, Enum a) => Integral a where
-- | integer division truncated toward zero
- quot :: a -> a -> a
+ quot :: a -> a -> a
-- | integer remainder, satisfying
--
-- > (x `quot` y)*y + (x `rem` y) == x
- rem :: a -> a -> a
+ rem :: a -> a -> a
-- | integer division truncated toward negative infinity
- div :: a -> a -> a
+ div :: a -> a -> a
-- | integer modulus, satisfying
--
-- > (x `div` y)*y + (x `mod` y) == x
- mod :: a -> a -> a
+ mod :: a -> a -> a
-- | simultaneous 'quot' and 'rem'
- quotRem :: a -> a -> (a,a)
+ quotRem :: a -> a -> (a,a)
-- | simultaneous 'div' and 'mod'
- divMod :: a -> a -> (a,a)
+ divMod :: a -> a -> (a,a)
-- | conversion to 'Integer'
- toInteger :: a -> Integer
+ toInteger :: a -> Integer
- 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
+ {-# INLINE quot #-}
+ {-# INLINE rem #-}
+ {-# INLINE div #-}
+ {-# INLINE mod #-}
+ 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
-- | Fractional numbers, supporting real division.
--
-- Minimal complete definition: 'fromRational' and ('recip' or @('/')@)
class (Num a) => Fractional a where
-- | fractional division
- (/) :: a -> a -> a
+ (/) :: a -> a -> a
-- | reciprocal fraction
- recip :: a -> a
+ recip :: a -> a
-- | Conversion from a 'Rational' (that is @'Ratio' 'Integer'@).
-- A floating literal stands for an application of 'fromRational'
-- to a value of type 'Rational', so such literals have type
-- @('Fractional' a) => a@.
- fromRational :: Rational -> a
+ fromRational :: Rational -> a
- recip x = 1 / x
- x / y = x * recip y
+ {-# INLINE recip #-}
+ {-# INLINE (/) #-}
+ recip x = 1 / x
+ x / y = x * recip y
-- | Extracting components of fractions.
--
--
-- The default definitions of the 'ceiling', 'floor', 'truncate'
-- and 'round' functions are in terms of 'properFraction'.
- properFraction :: (Integral b) => a -> (b,a)
+ properFraction :: (Integral b) => a -> (b,a)
-- | @'truncate' x@ returns the integer nearest @x@ between zero and @x@
- truncate :: (Integral b) => a -> b
- -- | @'round' x@ returns the nearest integer to @x@
- round :: (Integral b) => a -> b
+ truncate :: (Integral b) => a -> b
+ -- | @'round' x@ returns the nearest integer to @x@;
+ -- the even integer if @x@ is equidistant between two integers
+ round :: (Integral b) => a -> b
-- | @'ceiling' x@ returns the least integer not less than @x@
- ceiling :: (Integral b) => a -> b
+ ceiling :: (Integral b) => a -> b
-- | @'floor' x@ returns the greatest integer not greater than @x@
- floor :: (Integral b) => a -> b
+ floor :: (Integral b) => a -> b
- truncate x = m where (m,_) = properFraction x
+ {-# INLINE truncate #-}
+ 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
+ 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
+ _ -> error "round default defn: Bad value"
- ceiling x = if r > 0 then n + 1 else n
- where (n,r) = properFraction x
+ 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
+ floor x = if r < 0 then n - 1 else n
+ where (n,r) = properFraction x
\end{code}
These 'numeric' enumerations come straight from the Report
\begin{code}
-numericEnumFrom :: (Fractional a) => a -> [a]
-numericEnumFrom = iterate (+1)
+numericEnumFrom :: (Fractional a) => a -> [a]
+numericEnumFrom n = n `seq` (n : numericEnumFrom (n + 1))
-numericEnumFromThen :: (Fractional a) => a -> a -> [a]
-numericEnumFromThen n m = iterate (+(m-n)) n
+numericEnumFromThen :: (Fractional a) => a -> a -> [a]
+numericEnumFromThen n m = n `seq` m `seq` (n : numericEnumFromThen m (m+m-n))
numericEnumFromTo :: (Ord a, Fractional a) => a -> a -> [a]
numericEnumFromTo n m = takeWhile (<= m + 1/2) (numericEnumFrom n)
numericEnumFromThenTo :: (Ord a, Fractional a) => a -> a -> a -> [a]
-numericEnumFromThenTo e1 e2 e3 = takeWhile pred (numericEnumFromThen e1 e2)
- where
- mid = (e2 - e1) / 2
- pred | e2 >= e1 = (<= e3 + mid)
- | otherwise = (>= e3 + mid)
+numericEnumFromThenTo e1 e2 e3
+ = takeWhile predicate (numericEnumFromThen e1 e2)
+ where
+ mid = (e2 - e1) / 2
+ predicate | e2 >= e1 = (<= e3 + mid)
+ | otherwise = (>= e3 + mid)
\end{code}
%*********************************************************
-%* *
+%* *
\subsection{Instances for @Int@}
-%* *
+%* *
%*********************************************************
\begin{code}
instance Real Int where
- toRational x = toInteger x % 1
-
-instance Integral Int where
- toInteger i = int2Integer i -- give back a full-blown Integer
-
- a `quot` 0 = divZeroError
- a `quot` b = a `quotInt` b
-
- a `rem` 0 = divZeroError
- a `rem` b = a `remInt` b
-
- a `div` 0 = divZeroError
- a `div` b = a `divInt` b
-
- a `mod` 0 = divZeroError
- a `mod` b = a `modInt` b
-
- a `quotRem` 0 = divZeroError
- a `quotRem` b = a `quotRemInt` b
-
- a `divMod` 0 = divZeroError
- a `divMod` b = a `divModInt` b
+ toRational x = toInteger x % 1
+
+instance Integral Int where
+ toInteger (I# i) = smallInteger i
+
+ a `quot` b
+ | b == 0 = divZeroError
+ | a == minBound && b == (-1) = overflowError
+ | otherwise = a `quotInt` b
+
+ a `rem` b
+ | b == 0 = divZeroError
+ | a == minBound && b == (-1) = overflowError
+ | otherwise = a `remInt` b
+
+ a `div` b
+ | b == 0 = divZeroError
+ | a == minBound && b == (-1) = overflowError
+ | otherwise = a `divInt` b
+
+ a `mod` b
+ | b == 0 = divZeroError
+ | a == minBound && b == (-1) = overflowError
+ | otherwise = a `modInt` b
+
+ a `quotRem` b
+ | b == 0 = divZeroError
+ | a == minBound && b == (-1) = overflowError
+ | otherwise = a `quotRemInt` b
+
+ a `divMod` b
+ | b == 0 = divZeroError
+ | a == minBound && b == (-1) = overflowError
+ | otherwise = a `divModInt` b
\end{code}
%*********************************************************
-%* *
+%* *
\subsection{Instances for @Integer@}
-%* *
+%* *
%*********************************************************
\begin{code}
instance Real Integer where
- toRational x = x % 1
+ toRational x = x % 1
instance Integral Integer where
- toInteger n = n
+ toInteger n = n
- a `quot` 0 = divZeroError
+ _ `quot` 0 = divZeroError
n `quot` d = n `quotInteger` d
- a `rem` 0 = divZeroError
+ _ `rem` 0 = divZeroError
n `rem` d = n `remInteger` d
- a `divMod` 0 = divZeroError
- a `divMod` b = a `divModInteger` b
+ _ `divMod` 0 = divZeroError
+ a `divMod` b = case a `divModInteger` b of
+ (# x, y #) -> (x, y)
- a `quotRem` 0 = divZeroError
- a `quotRem` b = a `quotRemInteger` b
+ _ `quotRem` 0 = divZeroError
+ a `quotRem` b = case a `quotRemInteger` b of
+ (# q, r #) -> (q, r)
-- use the defaults for div & mod
\end{code}
%*********************************************************
-%* *
+%* *
\subsection{Instances for @Ratio@}
-%* *
+%* *
%*********************************************************
\begin{code}
-instance (Integral a) => Ord (Ratio a) where
+instance (Integral a) => Ord (Ratio a) where
{-# SPECIALIZE instance Ord Rational #-}
- (x:%y) <= (x':%y') = x * y' <= x' * y
- (x:%y) < (x':%y') = x * y' < x' * y
+ (x:%y) <= (x':%y') = x * y' <= x' * y
+ (x:%y) < (x':%y') = x * y' < x' * y
-instance (Integral a) => Num (Ratio a) where
+instance (Integral a) => Num (Ratio a) where
{-# SPECIALIZE instance Num Rational #-}
- (x:%y) + (x':%y') = reduce (x*y' + x'*y) (y*y')
- (x:%y) - (x':%y') = reduce (x*y' - x'*y) (y*y')
- (x:%y) * (x':%y') = reduce (x * x') (y * y')
- negate (x:%y) = (-x) :% y
- abs (x:%y) = abs x :% y
- signum (x:%_) = signum x :% 1
- fromInteger x = fromInteger x :% 1
-
-instance (Integral a) => Fractional (Ratio a) where
+ (x:%y) + (x':%y') = reduce (x*y' + x'*y) (y*y')
+ (x:%y) - (x':%y') = reduce (x*y' - x'*y) (y*y')
+ (x:%y) * (x':%y') = reduce (x * x') (y * y')
+ negate (x:%y) = (-x) :% y
+ abs (x:%y) = abs x :% y
+ signum (x:%_) = signum x :% 1
+ fromInteger x = fromInteger x :% 1
+
+instance (Integral a) => Fractional (Ratio a) where
{-# SPECIALIZE instance Fractional Rational #-}
- (x:%y) / (x':%y') = (x*y') % (y*x')
- recip (x:%y) = y % x
+ (x:%y) / (x':%y') = (x*y') % (y*x')
+ recip (x:%y) = y % x
fromRational (x:%y) = fromInteger x :% fromInteger y
-instance (Integral a) => Real (Ratio a) where
+instance (Integral a) => Real (Ratio a) where
{-# SPECIALIZE instance Real Rational #-}
- toRational (x:%y) = toInteger x :% toInteger y
+ toRational (x:%y) = toInteger x :% toInteger y
-instance (Integral a) => RealFrac (Ratio a) where
+instance (Integral a) => RealFrac (Ratio a) where
{-# SPECIALIZE instance RealFrac Rational #-}
properFraction (x:%y) = (fromInteger (toInteger q), r:%y)
- where (q,r) = quotRem x y
+ where (q,r) = quotRem x y
instance (Integral a) => Show (Ratio a) where
{-# SPECIALIZE instance Show Rational #-}
- showsPrec p (x:%y) = showParen (p > ratioPrec) $
- showsPrec ratioPrec1 x .
- showString "%" . -- H98 report has spaces round the %
- -- but we removed them [May 04]
- showsPrec ratioPrec1 y
-
-instance (Integral a) => Enum (Ratio a) where
+ showsPrec p (x:%y) = showParen (p > ratioPrec) $
+ showsPrec ratioPrec1 x .
+ showString " % " .
+ -- H98 report has spaces round the %
+ -- but we removed them [May 04]
+ -- and added them again for consistency with
+ -- Haskell 98 [Sep 08, #1920]
+ showsPrec ratioPrec1 y
+
+instance (Integral a) => Enum (Ratio a) where
{-# SPECIALIZE instance Enum Rational #-}
- succ x = x + 1
- pred x = x - 1
+ succ x = x + 1
+ pred x = x - 1
- toEnum n = fromInteger (int2Integer n) :% 1
+ toEnum n = fromIntegral n :% 1
fromEnum = fromInteger . truncate
- enumFrom = numericEnumFrom
- enumFromThen = numericEnumFromThen
- enumFromTo = numericEnumFromTo
- enumFromThenTo = numericEnumFromThenTo
+ enumFrom = numericEnumFrom
+ enumFromThen = numericEnumFromThen
+ enumFromTo = numericEnumFromTo
+ enumFromThenTo = numericEnumFromThenTo
\end{code}
%*********************************************************
-%* *
+%* *
\subsection{Coercions}
-%* *
+%* *
%*********************************************************
\begin{code}
\end{code}
%*********************************************************
-%* *
+%* *
\subsection{Overloaded numeric functions}
-%* *
+%* *
%*********************************************************
\begin{code}
-- | Converts a possibly-negative 'Real' value to a string.
showSigned :: (Real a)
- => (a -> ShowS) -- ^ a function that can show unsigned values
- -> Int -- ^ the precedence of the enclosing context
- -> a -- ^ the value to show
+ => (a -> ShowS) -- ^ a function that can show unsigned values
+ -> Int -- ^ the precedence of the enclosing context
+ -> a -- ^ the value to show
-> ShowS
showSigned showPos p x
| x < 0 = showParen (p > 6) (showChar '-' . showPos (-x))
| otherwise = showPos x
-even, odd :: (Integral a) => a -> Bool
-even n = n `rem` 2 == 0
-odd = not . even
+even, odd :: (Integral a) => a -> Bool
+even n = n `rem` 2 == 0
+odd = not . even
-------------------------------------------------------
-- | raise a number to a non-negative integral power
{-# 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"
+ Integer -> Integer -> Integer,
+ Integer -> Int -> Integer,
+ Int -> Int -> Int #-}
+(^) :: (Num a, Integral b) => a -> b -> a
+x0 ^ y0 | y0 < 0 = error "Negative exponent"
+ | y0 == 0 = 1
+ | otherwise = f x0 y0
+ where -- f : x0 ^ y0 = x ^ y
+ f x y | even y = f (x * x) (y `quot` 2)
+ | y == 1 = x
+ | otherwise = g (x * x) ((y - 1) `quot` 2) x
+ -- g : x0 ^ y0 = (x ^ y) * z
+ g x y z | even y = g (x * x) (y `quot` 2) z
+ | y == 1 = x * z
+ | otherwise = g (x * x) ((y - 1) `quot` 2) (x * z)
-- | raise a number to an integral power
{-# SPECIALISE (^^) ::
- Rational -> Int -> Rational #-}
-(^^) :: (Fractional a, Integral b) => a -> b -> a
-x ^^ n = if n >= 0 then x^n else recip (x^(negate n))
+ Rational -> Int -> Rational #-}
+(^^) :: (Fractional a, Integral b) => a -> b -> a
+x ^^ n = if n >= 0 then x^n else recip (x^(negate n))
-------------------------------------------------------
-- | @'gcd' x y@ is the greatest (positive) integer that divides both @x@
-- and @y@; for example @'gcd' (-3) 6@ = @3@, @'gcd' (-3) (-6)@ = @3@,
-- @'gcd' 0 4@ = @4@. @'gcd' 0 0@ raises a runtime error.
-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)
+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)
-- | @'lcm' x y@ is the smallest positive integer that both @x@ and @y@ divide.
-lcm :: (Integral a) => a -> a -> a
+lcm :: (Integral a) => a -> a -> a
{-# SPECIALISE lcm :: Int -> Int -> Int #-}
-lcm _ 0 = 0
-lcm 0 _ = 0
-lcm x y = abs ((x `quot` (gcd x y)) * y)
-
+lcm _ 0 = 0
+lcm 0 _ = 0
+lcm x y = abs ((x `quot` (gcd x y)) * y)
+#ifdef OPTIMISE_INTEGER_GCD_LCM
{-# RULES
"gcd/Int->Int->Int" gcd = gcdInt
-"gcd/Integer->Integer->Integer" gcd = gcdInteger
+"gcd/Integer->Integer->Integer" gcd = gcdInteger'
"lcm/Integer->Integer->Integer" lcm = lcmInteger
#-}
+gcdInteger' :: Integer -> Integer -> Integer
+gcdInteger' 0 0 = error "GHC.Real.gcdInteger': gcd 0 0 is undefined"
+gcdInteger' a b = gcdInteger a b
+
+gcdInt :: Int -> Int -> Int
+gcdInt 0 0 = error "GHC.Real.gcdInt: gcd 0 0 is undefined"
+gcdInt a b = fromIntegral (gcdInteger (fromIntegral a) (fromIntegral b))
+#endif
+
integralEnumFrom :: (Integral a, Bounded a) => a -> [a]
integralEnumFrom n = map fromInteger [toInteger n .. toInteger (maxBound `asTypeOf` n)]