Remove from `base` obsolete CPP for `integer-gmp`
authorAlec Theriault <alec.theriault@gmail.com>
Tue, 8 Jan 2019 18:41:50 +0000 (10:41 -0800)
committerBen Gamari <ben@smart-cactus.org>
Wed, 16 Jan 2019 19:17:11 +0000 (14:17 -0500)
  * `GHC.Natural` now exports the same functions (regardless of integer backend)
  * remove unnecessary CPP around instances
  * remove the 'OPTIMISE_INTEGER_GCD_LCM' flag - almost all of those optimizations
    now work regardless of which integer backend is used

Note that some CPP still remains for situations where there are backend-specific
optimization hacks (like a more efficient GMP-only `gcd` for `Int#` and `Word#`).

libraries/base/Data/Bits.hs
libraries/base/GHC/Enum.hs
libraries/base/GHC/Natural.hs
libraries/base/GHC/Num.hs
libraries/base/GHC/Read.hs
libraries/base/GHC/Real.hs
libraries/base/base.cabal

index 18110b5..4226f8e 100644 (file)
@@ -63,10 +63,6 @@ import GHC.Num
 import GHC.Base
 import GHC.Real
 
-#if defined(MIN_VERSION_integer_gmp)
-import GHC.Integer.GMP.Internals (bitInteger, popCountInteger)
-#endif
-
 infixl 8 `shift`, `rotate`, `shiftL`, `shiftR`, `rotateL`, `rotateR`
 infixl 7 .&.
 infixl 6 `xor`
@@ -526,13 +522,8 @@ instance Bits Integer where
    testBit x (I# i) = testBitInteger x i
    zeroBits   = 0
 
-#if defined(MIN_VERSION_integer_gmp)
    bit (I# i#) = bitInteger i#
    popCount x  = I# (popCountInteger x)
-#else
-   bit        = bitDefault
-   popCount   = popCountDefault
-#endif
 
    rotate x i = shift x i   -- since an Integer never wraps around
 
@@ -540,7 +531,6 @@ instance Bits Integer where
    bitSize _  = errorWithoutStackTrace "Data.Bits.bitSize(Integer)"
    isSigned _ = True
 
-#if defined(MIN_VERSION_integer_gmp)
 -- | @since 4.8.0
 instance Bits Natural where
    (.&.) = andNatural
@@ -563,50 +553,6 @@ instance Bits Natural where
    bitSizeMaybe _ = Nothing
    bitSize _  = errorWithoutStackTrace "Data.Bits.bitSize(Natural)"
    isSigned _ = False
-#else
--- | @since 4.8.0.0
-instance Bits Natural where
-  Natural n .&. Natural m = Natural (n .&. m)
-  {-# INLINE (.&.) #-}
-  Natural n .|. Natural m = Natural (n .|. m)
-  {-# INLINE (.|.) #-}
-  xor (Natural n) (Natural m) = Natural (xor n m)
-  {-# INLINE xor #-}
-  complement _ = errorWithoutStackTrace "Bits.complement: Natural complement undefined"
-  {-# INLINE complement #-}
-  shift (Natural n) = Natural . shift n
-  {-# INLINE shift #-}
-  rotate (Natural n) = Natural . rotate n
-  {-# INLINE rotate #-}
-  bit = Natural . bit
-  {-# INLINE bit #-}
-  setBit (Natural n) = Natural . setBit n
-  {-# INLINE setBit #-}
-  clearBit (Natural n) = Natural . clearBit n
-  {-# INLINE clearBit #-}
-  complementBit (Natural n) = Natural . complementBit n
-  {-# INLINE complementBit #-}
-  testBit (Natural n) = testBit n
-  {-# INLINE testBit #-}
-  bitSizeMaybe _ = Nothing
-  {-# INLINE bitSizeMaybe #-}
-  bitSize = errorWithoutStackTrace "Natural: bitSize"
-  {-# INLINE bitSize #-}
-  isSigned _ = False
-  {-# INLINE isSigned #-}
-  shiftL (Natural n) = Natural . shiftL n
-  {-# INLINE shiftL #-}
-  shiftR (Natural n) = Natural . shiftR n
-  {-# INLINE shiftR #-}
-  rotateL (Natural n) = Natural . rotateL n
-  {-# INLINE rotateL #-}
-  rotateR (Natural n) = Natural . rotateR n
-  {-# INLINE rotateR #-}
-  popCount (Natural n) = popCount n
-  {-# INLINE popCount #-}
-  zeroBits = Natural 0
-
-#endif
 
 -----------------------------------------------------------------------------
 
index 18850ac..bf85ca0 100644 (file)
@@ -919,7 +919,6 @@ dn_list x0 delta lim = go (x0 :: Integer)
 -- Natural
 ------------------------------------------------------------------------
 
-#if defined(MIN_VERSION_integer_gmp)
 -- | @since 4.8.0.0
 instance Enum Natural where
     succ n = n `plusNatural`  wordToNaturalBase 1##
@@ -927,11 +926,13 @@ instance Enum Natural where
 
     toEnum = intToNatural
 
+#if defined(MIN_VERSION_integer_gmp)
     fromEnum (NatS# w)
       | i >= 0    = i
       | otherwise = errorWithoutStackTrace "fromEnum: out of Int range"
       where
         i = I# (word2Int# w)
+#endif
     fromEnum n = fromEnum (naturalToInteger n)
 
     enumFrom x        = enumDeltaNatural      x (wordToNaturalBase 1##)
@@ -962,31 +963,6 @@ enumNegDeltaToNatural x0 ndelta lim = go x0
          | x >= ndelta = x : go (x-ndelta)
          | otherwise   = [x]
 
-#else
-
--- | @since 4.8.0.0
-instance Enum Natural where
-  pred (Natural 0) = errorWithoutStackTrace "Natural.pred: 0"
-  pred (Natural n) = Natural (pred n)
-  {-# INLINE pred #-}
-  succ (Natural n) = Natural (succ n)
-  {-# INLINE succ #-}
-  fromEnum (Natural n) = fromEnum n
-  {-# INLINE fromEnum #-}
-  toEnum n | n < 0     = errorWithoutStackTrace "Natural.toEnum: negative"
-           | otherwise = Natural (toEnum n)
-  {-# INLINE toEnum #-}
-
-  enumFrom     = coerce (enumFrom     :: Integer -> [Integer])
-  enumFromThen x y
-    | x <= y    = coerce (enumFromThen :: Integer -> Integer -> [Integer]) x y
-    | otherwise = enumFromThenTo x y (wordToNaturalBase 0##)
-
-  enumFromTo   = coerce (enumFromTo   :: Integer -> Integer -> [Integer])
-  enumFromThenTo
-    = coerce (enumFromThenTo :: Integer -> Integer -> Integer -> [Integer])
-
-#endif
 
 -- Instances from GHC.Types
 
index 2cc255e..fef76df 100644 (file)
@@ -42,19 +42,15 @@ module GHC.Natural
     , quotRemNatural
     , quotNatural
     , remNatural
-#if defined(MIN_VERSION_integer_gmp)
     , gcdNatural
     , lcmNatural
-#endif
       -- * Bits
     , andNatural
     , orNatural
     , xorNatural
     , bitNatural
     , testBitNatural
-#if defined(MIN_VERSION_integer_gmp)
     , popCountNatural
-#endif
     , shiftLNatural
     , shiftRNatural
       -- * Conversions
@@ -439,6 +435,15 @@ naturalFromInteger n
   | True                   = underflowError
 {-# INLINE naturalFromInteger #-}
 
+
+-- | Compute greatest common divisor.
+gcdNatural :: Natural -> Natural -> Natural
+gcdNatural (Natural n) (Natural m) = Natural (n `gcdInteger` m)
+
+-- | Compute lowest common multiple.
+lcmNatural :: Natural -> Natural -> Natural
+lcmNatural (Natural n) (Natural m) = Natural (n `lcmInteger` m)
+
 -- | 'Natural' subtraction. Returns 'Nothing's for non-positive results.
 --
 -- @since 4.8.0.0
@@ -460,7 +465,9 @@ plusNatural (Natural x) (Natural y) = Natural (x `plusInteger` y)
 {-# CONSTANT_FOLDED plusNatural #-}
 
 minusNatural :: Natural -> Natural -> Natural
-minusNatural (Natural x) (Natural y) = Natural (x `minusInteger` y)
+minusNatural (Natural x) (Natural y)
+  = if z `ltInteger` wordToInteger 0## then underflowError else Natural z
+  where z = x `minusInteger` y
 {-# CONSTANT_FOLDED minusNatural #-}
 
 timesNatural :: Natural -> Natural -> Natural
@@ -493,6 +500,9 @@ testBitNatural :: Natural -> Int -> Bool
 testBitNatural (Natural n) (I# i) = testBitInteger n i
 -- {-# CONSTANT_FOLDED testBitNatural #-}
 
+popCountNatural :: Natural -> Int
+popCountNatural (Natural n) = I# (popCountInteger n)
+
 bitNatural :: Int# -> Natural
 bitNatural i#
   | isTrue# (i# <# WORD_SIZE_IN_BITS#) = wordToNaturalBase (1## `uncheckedShiftL#` i#)
index 1bf1681..023ccb3 100644 (file)
@@ -24,9 +24,6 @@ module GHC.Num (module GHC.Num, module GHC.Integer, module GHC.Natural) where
 import GHC.Base
 import GHC.Integer
 import GHC.Natural
-#if !defined(MIN_VERSION_integer_gmp)
-import {-# SOURCE #-} GHC.Exception.Type (underflowException)
-#endif
 
 infixl 7  *
 infixl 6  +, -
@@ -125,7 +122,6 @@ instance  Num Integer  where
     abs = absInteger
     signum = signumInteger
 
-#if defined(MIN_VERSION_integer_gmp)
 -- | Note that `Natural`'s 'Num' instance isn't a ring: no element but 0 has an
 -- additive inverse. It is a semiring though.
 --
@@ -140,25 +136,3 @@ instance  Num Natural  where
     abs = id
     signum = signumNatural
 
-#else
--- | Note that `Natural`'s 'Num' instance isn't a ring: no element but 0 has an
--- additive inverse. It is a semiring though.
---
--- @since 4.8.0.0
-instance Num Natural where
-  Natural n + Natural m = Natural (n + m)
-  {-# INLINE (+) #-}
-  Natural n * Natural m = Natural (n * m)
-  {-# INLINE (*) #-}
-  Natural n - Natural m
-      | m > n     = raise# underflowException
-      | otherwise = Natural (n - m)
-  {-# INLINE (-) #-}
-  abs (Natural n) = Natural n
-  {-# INLINE abs #-}
-  signum (Natural n) = Natural (signum n)
-  {-# INLINE signum #-}
-  fromInteger = naturalFromInteger
-  {-# INLINE fromInteger #-}
-
-#endif
index 26dca6a..2283942 100644 (file)
@@ -618,17 +618,10 @@ instance Read Integer where
   readList     = readListDefault
 
 
-#if defined(MIN_VERSION_integer_gmp)
 -- | @since 4.8.0.0
 instance Read Natural where
   readsPrec d = map (\(n, s) -> (fromInteger n, s))
                   . filter ((>= 0) . (\(x,_)->x)) . readsPrec d
-#else
--- | @since 4.8.0.0
-instance Read Natural where
-    readsPrec d = map (\(n, s) -> (Natural n, s))
-                  . filter ((>= 0) . (\(x,_)->x)) . readsPrec d
-#endif
 
 -- | @since 2.01
 instance Read Float where
index cb6e9e9..2a9494f 100644 (file)
@@ -31,12 +31,8 @@ import {-# SOURCE #-} GHC.Exception( divZeroException, overflowException
                                    , underflowException
                                    , ratioZeroDenomException )
 
-#if defined(OPTIMISE_INTEGER_GCD_LCM)
-# if defined(MIN_VERSION_integer_gmp)
+#if defined(MIN_VERSION_integer_gmp)
 import GHC.Integer.GMP.Internals
-# else
-#  error unsupported OPTIMISE_INTEGER_GCD_LCM configuration
-# endif
 #endif
 
 infixr 8  ^, ^^
@@ -412,17 +408,9 @@ instance Integral Word where
 instance  Real Integer  where
     toRational x        =  x :% 1
 
-#if defined(MIN_VERSION_integer_gmp)
--- | @since 4.8.0.0
-instance Real Natural where
-    toRational (NatS# w)  = toRational (W# w)
-    toRational (NatJ# bn) = toRational (Jp# bn)
-#else
 -- | @since 4.8.0.0
 instance Real Natural where
-  toRational (Natural a) = toRational a
-  {-# INLINE toRational #-}
-#endif
+    toRational n = naturalToInteger n :% 1
 
 -- Note [Integer division constant folding]
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -466,7 +454,6 @@ instance  Integral Integer where
     n `quotRem` d = case n `quotRemInteger` d of
                       (# q, r #) -> (q, r)
 
-#if defined(MIN_VERSION_integer_gmp)
 -- | @since 4.8.0.0
 instance Integral Natural where
     toInteger = naturalToInteger
@@ -478,30 +465,6 @@ instance Integral Natural where
     quotRem = quotRemNatural
     quot    = quotNatural
     rem     = remNatural
-#else
--- | @since 4.8.0.0
-instance Integral Natural where
-    {-# INLINE toInteger #-}
-    toInteger (Natural a) = a
-
-    {-# INLINE quot #-}
-    Natural a `quot` Natural b = Natural (a `quot` b)
-
-    {-# INLINE rem #-}
-    Natural a `rem` Natural b = Natural (a `rem` b)
-
-    {-# INLINE div #-}
-    Natural a `div` Natural b = Natural (a `div` b)
-
-    {-# INLINE mod #-}
-    Natural a `mod` Natural b = Natural (a `mod` b)
-
-    {-# INLINE divMod #-}
-    Natural a `divMod` Natural b = coerce (a `divMod` b)
-
-    {-# INLINE quotRem #-}
-    Natural a `quotRem` Natural b = coerce (a `quotRem` b)
-#endif
 
 --------------------------------------------------------------
 -- Instances for @Ratio@
@@ -789,24 +752,27 @@ lcm _ 0         =  0
 lcm 0 _         =  0
 lcm x y         =  abs ((x `quot` (gcd x y)) * y)
 
-#if defined(OPTIMISE_INTEGER_GCD_LCM)
 {-# RULES
-"gcd/Int->Int->Int"             gcd = gcdInt'
 "gcd/Integer->Integer->Integer" gcd = gcdInteger
 "lcm/Integer->Integer->Integer" lcm = lcmInteger
 "gcd/Natural->Natural->Natural" gcd = gcdNatural
 "lcm/Natural->Natural->Natural" lcm = lcmNatural
  #-}
 
+#if defined(MIN_VERSION_integer_gmp)
+-- GMP defines a more efficient Int# and Word# GCD
+
 gcdInt' :: Int -> Int -> Int
 gcdInt' (I# x) (I# y) = I# (gcdInt x y)
 
+gcdWord' :: Word -> Word -> Word
+gcdWord' (W# x) (W# y) = W# (gcdWord x y)
+
 {-# RULES
+"gcd/Int->Int->Int"             gcd = gcdInt'
 "gcd/Word->Word->Word"          gcd = gcdWord'
  #-}
 
-gcdWord' :: Word -> Word -> Word
-gcdWord' (W# x) (W# y) = W# (gcdWord x y)
 #endif
 
 integralEnumFrom :: (Integral a, Bounded a) => a -> [a]
index f02ff08..4e809e7 100644 (file)
@@ -106,7 +106,6 @@ Library
 
     if flag(integer-gmp)
         build-depends: integer-gmp ^>= 1.0.1
-        cpp-options: -DOPTIMISE_INTEGER_GCD_LCM
 
     exposed-modules:
         Control.Applicative