\begin{code}
-{-# OPTIONS_GHC -XNoImplicitPrelude #-}
+{-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, UnboxedTuples #-}
{-# OPTIONS_HADDOCK hide #-}
-----------------------------------------------------------------------------
-- |
\begin{code}
-- | Rational numbers, with numerator and denominator of some 'Integral' type.
-data (Integral a) => Ratio a = !a :% !a deriving (Eq)
+data 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
a `quot` b
| b == 0 = divZeroError
- | a == minBound && b == (-1) = overflowError
+ | b == (-1) && a == minBound = overflowError -- Note [Order of tests]
+ -- in GHC.Int
| otherwise = a `quotInt` b
a `rem` b
| b == 0 = divZeroError
- | a == minBound && b == (-1) = overflowError
+ | b == (-1) && a == minBound = overflowError -- Note [Order of tests]
+ -- in GHC.Int
| otherwise = a `remInt` b
a `div` b
| b == 0 = divZeroError
- | a == minBound && b == (-1) = overflowError
+ | b == (-1) && a == minBound = overflowError -- Note [Order of tests]
+ -- in GHC.Int
| otherwise = a `divInt` b
a `mod` b
| b == 0 = divZeroError
- | a == minBound && b == (-1) = overflowError
+ | b == (-1) && a == minBound = overflowError -- Note [Order of tests]
+ -- in GHC.Int
| otherwise = a `modInt` b
a `quotRem` b
| b == 0 = divZeroError
- | a == minBound && b == (-1) = overflowError
+ | b == (-1) && a == minBound = overflowError -- Note [Order of tests]
+ -- in GHC.Int
| otherwise = a `quotRemInt` b
a `divMod` b
| b == 0 = divZeroError
- | a == minBound && b == (-1) = overflowError
+ | b == (-1) && a == minBound = overflowError -- Note [Order of tests]
+ -- in GHC.Int
| otherwise = a `divModInt` b
\end{code}
Integer -> Integer -> Integer,
Integer -> Int -> Integer,
Int -> Int -> Int #-}
+{-# INLINABLE (^) #-} -- See Note [Inlining (^)]
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = error "Negative exponent"
| y0 == 0 = 1
-- | raise a number to an integral power
(^^) :: (Fractional a, Integral b) => a -> b -> a
+{-# INLINABLE (^^) #-} -- See Note [Inlining (^)
x ^^ n = if n >= 0 then x^n else recip (x^(negate n))
+{- Note [Inlining (^)
+ ~~~~~~~~~~~~~~~~~~~~~
+ The INLINABLE pragma allows (^) to be specialised at its call sites.
+ If it is called repeatedly at the same type, that can make a huge
+ difference, because of those constants which can be repeatedly
+ calculated.
+
+ Currently the fromInteger calls are not floated because we get
+ \d1 d2 x y -> blah
+ after the gentle round of simplification. -}
+
-------------------------------------------------------
-- Special power functions for Rational
--
in if even e then (nn :% dd) else (negate nn :% dd)
-------------------------------------------------------
--- | @'gcd' x y@ is the greatest (positive) integer that divides both @x@
+-- | @'gcd' x y@ is the greatest (nonnegative) 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' 0 4@ = @4@. @'gcd' 0 0@ = @0@.
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)
#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