packages feed

scientific 0.3.6.2 → 0.3.7.0

raw patch · 9 files changed

+258/−126 lines, 9 filesdep +invalid-cabal-flag-settingsdep +template-haskelldep −tasty-ant-xmldep ~QuickCheckdep ~basedep ~binarynew-uploader

Dependencies added: invalid-cabal-flag-settings, template-haskell

Dependencies removed: tasty-ant-xml

Dependency ranges changed: QuickCheck, base, binary, bytestring, bytestring-builder, containers, deepseq, hashable, integer-logarithms, primitive, tasty, text

Files

bench/bench.hs view
@@ -57,6 +57,21 @@          , bgroup "dangerouslyBig" $ benchToBoundedInteger dangerouslyBig          , bgroup "64"             $ benchToBoundedInteger 64          ]++       , bgroup "read"+         [ benchRead "123456789.123456789"+         , benchRead "12345678900000000000.12345678900000000000000000"+         , benchRead "12345678900000000000.12345678900000000000000000e1234"+         ]++       , bgroup "division"+         [ bench (show n ++ " / " ++ show d) $ nf (uncurry (/)) t+         | t@(n, d) <-+           [ (0.4     , 20.0)+           , (0.4e-100, 0.2e50)+           ] :: [(Scientific, Scientific)]+         ]+        ]     where       pos :: Fractional a => a
changelog view
@@ -1,3 +1,14 @@+0.3.7.0++	* Make division (/) on Scientifics slightly more efficient.++	* Fix the Show instance to surround negative numbers with parentheses when+	necessary.++	* Add (Template Haskell) Lift Scientific instance++	* Mark modules as Safe or Trustworthy (Safe Haskell).+ 0.3.6.2 	* Due to a regression introduced in 0.3.4.14 the RealFrac methods 	and floatingOrInteger became vulnerable to a space blowup when
scientific.cabal view
@@ -1,6 +1,6 @@-name:                scientific-version:             0.3.6.2-synopsis:            Numbers represented using scientific notation+name:               scientific+version:            0.3.7.0+synopsis:           Numbers represented using scientific notation description:   "Data.Scientific" provides the number type 'Scientific'. Scientific numbers are   arbitrary precision and space efficient. They are represented using@@ -32,32 +32,36 @@   @'Integral's@ (like: 'Int') or @'RealFloat's@ (like: 'Double' or 'Float')   will always be bounded by the target type. -homepage:            https://github.com/basvandijk/scientific-bug-reports:         https://github.com/basvandijk/scientific/issues-license:             BSD3-license-file:        LICENSE-author:              Bas van Dijk-maintainer:          Bas van Dijk <v.dijk.bas@gmail.com>-category:            Data-build-type:          Simple-cabal-version:       >=1.10--extra-source-files:-  changelog--Tested-With: GHC == 7.6.3-           , GHC == 7.8.4-           , GHC == 7.10.3-           , GHC == 8.0.2-           , GHC == 8.2.2-           , GHC == 8.4.1+homepage:           https://github.com/basvandijk/scientific+bug-reports:        https://github.com/basvandijk/scientific/issues+license:            BSD3+license-file:       LICENSE+author:             Bas van Dijk+maintainer:         Bas van Dijk <v.dijk.bas@gmail.com>+category:           Data+build-type:         Simple+cabal-version:      >=1.10+extra-source-files: changelog+tested-with:+  GHC ==7.6.3+   || ==7.8.4+   || ==7.10.3+   || ==8.0.2+   || ==8.2.2+   || ==8.4.4+   || ==8.6.5+   || ==8.8.4+   || ==8.10.4+   || ==9.0.1  source-repository head   type:     git   location: git://github.com/basvandijk/scientific.git  flag bytestring-builder-  description: Depend on the bytestring-builder package for backwards compatibility.+  description:+    Depend on the bytestring-builder package for backwards compatibility.+   default:     False   manual:      False @@ -66,60 +70,89 @@   default:     False  library-  exposed-modules:     Data.ByteString.Builder.Scientific-                       Data.Scientific-                       Data.Text.Lazy.Builder.Scientific-  other-modules:       GHC.Integer.Compat-                       Utils-  other-extensions:    DeriveDataTypeable, BangPatterns-  ghc-options:         -Wall-  build-depends:       base        >= 4.3 && < 5-                     , integer-logarithms >= 1-                     , deepseq     >= 1.3-                     , text        >= 0.8-                     , hashable    >= 1.1.2-                     , primitive   >= 0.1-                     , containers  >= 0.1-                     , binary      >= 0.4.1+  exposed-modules:+    Data.ByteString.Builder.Scientific+    Data.Scientific+    Data.Text.Lazy.Builder.Scientific +  other-modules:+    GHC.Integer.Compat+    Utils++  other-extensions:+    BangPatterns+    DeriveDataTypeable+    Trustworthy++  ghc-options:      -Wall+  build-depends:+      base                >=4.5     && <4.16+    , binary              >=0.5.1   && <0.9+    , containers          >=0.4.2.1 && <0.7+    , deepseq             >=1.3.0.0 && <1.5+    , hashable            >=1.2.7.0 && <1.4+    , integer-logarithms  >=1.0.3.1 && <1.1+    , primitive           >=0.7.1.0 && <0.8+    , template-haskell    >=2.8     && <2.18+    , text                >=1.2.3.0 && <1.3+   if flag(bytestring-builder)-      build-depends: bytestring         >= 0.9    && < 0.10.4-                   , bytestring-builder >= 0.10.4 && < 0.11+    build-depends:+        bytestring          >=0.9    && <0.10.4+      , bytestring-builder  >=0.10.4 && <0.11+   else-      build-depends: bytestring         >= 0.10.4+    build-depends: bytestring >=0.10.4 && <0.12 -  if flag(integer-simple)-      build-depends: integer-simple+  if impl(ghc >=9.0)+    build-depends: base >=4.15++    if flag(integer-simple)+      build-depends: invalid-cabal-flag-settings <0+   else+    if flag(integer-simple)+      build-depends: integer-simple++    else       build-depends: integer-gmp -  hs-source-dirs:      src-  default-language:    Haskell2010+  if impl(ghc <8)+    other-extensions: TemplateHaskell +  if impl(ghc >= 9.0)+    -- these flags may abort compilation with GHC-8.10+    -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3295+    ghc-options: -Winferred-safe-imports -Wmissing-safe-haskell-mode++  hs-source-dirs:   src+  default-language: Haskell2010+ test-suite test-scientific   type:             exitcode-stdio-1.0   hs-source-dirs:   test   main-is:          test.hs   default-language: Haskell2010   ghc-options:      -Wall--  build-depends: scientific-               , base             >= 4.3 && < 5-               , binary           >= 0.4.1-               , tasty            >= 0.5-               , tasty-ant-xml    >= 1.0-               , tasty-hunit      >= 0.8-               , tasty-smallcheck >= 0.2-               , tasty-quickcheck >= 0.8-               , smallcheck       >= 1.0-               , QuickCheck       >= 2.5-               , text             >= 0.8+  build-depends:+      base+    , binary+    , QuickCheck        >=2.14.2+    , scientific+    , smallcheck        >=1.0+    , tasty             >=1.4.0.1+    , tasty-hunit       >=0.8+    , tasty-quickcheck  >=0.8+    , tasty-smallcheck  >=0.2+    , text    if flag(bytestring-builder)-      build-depends: bytestring         >= 0.9    && < 0.10.4-                   , bytestring-builder >= 0.10.4 && < 0.11+    build-depends:+        bytestring+      , bytestring-builder+   else-      build-depends: bytestring         >= 0.10.4+    build-depends: bytestring  benchmark bench-scientific   type:             exitcode-stdio-1.0@@ -127,6 +160,7 @@   main-is:          bench.hs   default-language: Haskell2010   ghc-options:      -O2-  build-depends:    scientific-                  , base        >= 4.3 && < 5-                  , criterion   >= 0.5+  build-depends:+      base+    , criterion   >=0.5+    , scientific
src/Data/ByteString/Builder/Scientific.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, OverloadedStrings #-}+{-# LANGUAGE CPP, OverloadedStrings, Safe #-}  module Data.ByteString.Builder.Scientific     ( scientificBuilder
src/Data/Scientific.hs view
@@ -4,7 +4,15 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE PatternGuards #-}+{-# LANGUAGE Trustworthy #-} +#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE DeriveLift #-}+{-# LANGUAGE StandaloneDeriving #-}+#else+{-# LANGUAGE TemplateHaskell #-}+#endif+ -- | -- Module      :  Data.Scientific -- Copyright   :  Bas van Dijk 2013@@ -48,7 +56,7 @@ -- -- This module is designed to be imported qualified: ----- @import Data.Scientific as Scientific@+-- @import qualified Data.Scientific as Scientific@ module Data.Scientific     ( Scientific @@ -98,7 +106,6 @@  import           Control.Exception            (throw, ArithException(DivideByZero)) import           Control.Monad                (mplus)-import           Control.Monad.ST             (runST) import           Control.DeepSeq              (NFData, rnf) import           Data.Binary                  (Binary, get, put) import           Data.Char                    (intToDigit, ord)@@ -108,7 +115,6 @@ import qualified Data.Map            as M     (Map, empty, insert, lookup) import           Data.Ratio                   ((%), numerator, denominator) import           Data.Typeable                (Typeable)-import qualified Data.Primitive.Array as Primitive import           Data.Word                    (Word8, Word16, Word32, Word64) import           Math.NumberTheory.Logarithms (integerLog10') import qualified Numeric                      (floatToDigits)@@ -129,16 +135,10 @@ import           Control.Applicative          ((<*>)) #endif -#if MIN_VERSION_base(4,5,0)-import           Data.Bits                    (unsafeShiftR)-#else-import           Data.Bits                    (shiftR)-#endif--import GHC.Integer        (quotRemInteger, quotInteger)-import GHC.Integer.Compat (divInteger)-import Utils              (roundTo)+import GHC.Integer.Compat (quotRemInteger, quotInteger, divInteger)+import Utils              (maxExpt, roundTo, magnitude) +import Language.Haskell.TH.Syntax (Lift (..))  ---------------------------------------------------------------------- -- Type@@ -163,6 +163,20 @@       -- in 'toDecimalDigits'.       --       -- Use 'normalize' to do manual normalization.+      --+      -- /WARNING:/ 'coefficient' and 'base10exponent' violate+      -- substantivity of 'Eq'.+      --+      -- >>> let x = scientific 1 2+      -- >>> let y = scientific 100 0+      -- >>> x == y+      -- True+      --+      -- but+      --+      -- >>> (coefficient x == coefficient y, base10Exponent x == base10Exponent y)+      -- (False,False)+      --      , base10Exponent :: {-# UNPACK #-} !Int       -- ^ The base-10 exponent of a scientific number.@@ -173,17 +187,32 @@ scientific :: Integer -> Int -> Scientific scientific = Scientific - ---------------------------------------------------------------------- -- Instances ---------------------------------------------------------------------- +#if __GLASGOW_HASKELL__ >= 800+-- | @since 0.3.7.0+deriving instance Lift Scientific+#else+instance Lift Scientific where+    lift (Scientific c e) = [| Scientific c e |]+#endif++ instance NFData Scientific where     rnf (Scientific _ _) = ()  -- | A hash can be safely calculated from a @Scientific@. No magnitude @10^e@ is -- calculated so there's no risk of a blowup in space or time when hashing -- scientific numbers coming from untrusted sources.+--+-- >>> import Data.Hashable (hash)+-- >>> let x = scientific 1 2+-- >>> let y = scientific 100 0+-- >>> (x == y, hash x == hash y)+-- (True,True)+-- instance Hashable Scientific where     hashWithSalt salt s = salt `hashWithSalt` c `hashWithSalt` e       where@@ -295,15 +324,23 @@ -- | /WARNING:/ 'recip' and '/' will throw an error when their outputs are -- <https://en.wikipedia.org/wiki/Repeating_decimal repeating decimals>. --+-- These methods also compute 'Integer' magnitudes (@10^e@). If these methods+-- are applied to arguments which have huge exponents this could fill up all+-- space and crash your program! So don't apply these methods to scientific+-- numbers coming from untrusted sources.+-- -- 'fromRational' will throw an error when the input 'Rational' is a repeating -- decimal.  Consider using 'fromRationalRepetend' for these rationals which -- will detect the repetition and indicate where it starts. instance Fractional Scientific where     recip = fromRational . recip . toRational-    {-# INLINABLE recip #-} -    x / y = fromRational $ toRational x / toRational y-    {-# INLINABLE (/) #-}+    Scientific c1 e1 / Scientific c2 e2+        | d < 0     = fromRational (x / (fromInteger (magnitude (-d))))+        | otherwise = fromRational (x *  fromInteger (magnitude   d))+      where+        d = e1 - e2+        x = c1 % c2      fromRational rational =         case mbRepetendIx of@@ -651,48 +688,10 @@ {-# INLINE toIntegral #-}  -------------------------------------------------------------------------- Exponentiation with a cache for the most common numbers.----------------------------------------------------------------------- --- | The same limit as in GHC.Float.-maxExpt :: Int-maxExpt = 324 -expts10 :: Primitive.Array Integer-expts10 = runST $ do-    ma <- Primitive.newArray maxExpt uninitialised-    Primitive.writeArray ma 0  1-    Primitive.writeArray ma 1 10-    let go !ix-          | ix == maxExpt = Primitive.unsafeFreezeArray ma-          | otherwise = do-              Primitive.writeArray ma  ix        xx-              Primitive.writeArray ma (ix+1) (10*xx)-              go (ix+2)-          where-            xx = x * x-            x  = Primitive.indexArray expts10 half-#if MIN_VERSION_base(4,5,0)-            !half = ix `unsafeShiftR` 1-#else-            !half = ix `shiftR` 1-#endif-    go 2 -uninitialised :: error-uninitialised = error "Data.Scientific: uninitialised element" --- | @magnitude e == 10 ^ e@-magnitude :: Num a => Int -> a-magnitude e | e < maxExpt = cachedPow10 e-            | otherwise   = cachedPow10 hi * 10 ^ (e - hi)-    where-      cachedPow10 = fromInteger . Primitive.indexArray expts10--      hi = maxExpt - 1-- ---------------------------------------------------------------------- -- Conversions ----------------------------------------------------------------------@@ -979,11 +978,16 @@  -- | See 'formatScientific' if you need more control over the rendering. instance Show Scientific where-    show s | coefficient s < 0 = '-':showPositive (-s)-           | otherwise         =     showPositive   s+    showsPrec d s+        | coefficient s < 0 = showParen (d > prefixMinusPrec) $+               showChar '-' . showPositive (-s)+        | otherwise         = showPositive   s       where-        showPositive :: Scientific -> String-        showPositive = fmtAsGeneric . toDecimalDigits+        prefixMinusPrec :: Int+        prefixMinusPrec = 6++        showPositive :: Scientific -> ShowS+        showPositive = showString . fmtAsGeneric . toDecimalDigits          fmtAsGeneric :: ([Int], Int) -> String         fmtAsGeneric x@(_is, e)
src/Data/Text/Lazy/Builder/Scientific.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, OverloadedStrings #-}+{-# LANGUAGE CPP, OverloadedStrings, Safe #-}  module Data.Text.Lazy.Builder.Scientific     ( scientificBuilder
src/GHC/Integer/Compat.hs view
@@ -1,7 +1,14 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE Trustworthy #-} -module GHC.Integer.Compat (divInteger) where+module GHC.Integer.Compat (divInteger, quotRemInteger, quotInteger) where +import GHC.Integer        (quotRemInteger, quotInteger)++#if MIN_VERSION_base(4,15,0)+import GHC.Integer (divInteger)+#else+ #ifdef MIN_VERSION_integer_simple  #if MIN_VERSION_integer_simple(0,1,1)@@ -20,4 +27,5 @@ divInteger = div #endif +#endif #endif
src/Utils.hs view
@@ -1,14 +1,28 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE ScopedTypeVariables #-}  module Utils     ( roundTo     , i2d+    , maxExpt+    , magnitude     ) where  import GHC.Base (Int(I#), Char(C#), chr#, ord#, (+#)) +import qualified Data.Primitive.Array as Primitive+import           Control.Monad.ST             (runST)++#if MIN_VERSION_base(4,5,0)+import           Data.Bits                    (unsafeShiftR)+#else+import           Data.Bits                    (shiftR)+#endif+ roundTo :: Int -> [Int] -> (Int, [Int]) roundTo d is =   case f d True is of@@ -34,3 +48,44 @@ {-# INLINE i2d #-} i2d :: Int -> Char i2d (I# i#) = C# (chr# (ord# '0'# +# i# ))++----------------------------------------------------------------------+-- Exponentiation with a cache for the most common numbers.+----------------------------------------------------------------------++-- | The same limit as in GHC.Float.+maxExpt :: Int+maxExpt = 324++expts10 :: Primitive.Array Integer+expts10 = runST $ do+    ma <- Primitive.newArray maxExpt uninitialised+    Primitive.writeArray ma 0  1+    Primitive.writeArray ma 1 10+    let go !ix+          | ix == maxExpt = Primitive.unsafeFreezeArray ma+          | otherwise = do+              Primitive.writeArray ma  ix        xx+              Primitive.writeArray ma (ix+1) (10*xx)+              go (ix+2)+          where+            xx = x * x+            x  = Primitive.indexArray expts10 half+#if MIN_VERSION_base(4,5,0)+            !half = ix `unsafeShiftR` 1+#else+            !half = ix `shiftR` 1+#endif+    go 2++uninitialised :: error+uninitialised = error "Data.Scientific: uninitialised element"++-- | @magnitude e == 10 ^ e@+magnitude :: Num a => Int -> a+magnitude e | e < maxExpt = cachedPow10 e+            | otherwise   = cachedPow10 hi * 10 ^ (e - hi)+    where+      cachedPow10 = fromInteger . Primitive.indexArray expts10++      hi = maxExpt - 1
test/test.hs view
@@ -18,7 +18,6 @@ import           Data.Word import           Data.Scientific                    as Scientific import           Test.Tasty-import           Test.Tasty.Runners.AntXML import           Test.Tasty.HUnit                          (testCase, (@?=), Assertion, assertBool) import qualified Test.SmallCheck                    as SC import qualified Test.SmallCheck.Series             as SC@@ -114,6 +113,9 @@    , testGroup "Formatting"     [ testProperty "read . show == id" $ \s -> read (show s) === s+    , testCase "show (Just 1)"    $ testShow (Just 1)    "Just 1.0"+    , testCase "show (Just 0)"    $ testShow (Just 0)    "Just 0.0"+    , testCase "show (Just (-1))" $ testShow (Just (-1)) "Just (-1.0)"      , testGroup "toDecimalDigits"       [ smallQuick "laws"@@ -279,13 +281,16 @@   ]  testMain :: TestTree -> IO ()-testMain = defaultMainWithIngredients (antXMLRunner:defaultIngredients)+testMain = defaultMainWithIngredients defaultIngredients  testReads :: String -> [(Scientific, String)] -> Assertion testReads inp out = reads inp @?= out  testRead :: String -> Scientific -> Assertion testRead inp out = read inp @?= out++testShow :: Maybe Scientific -> String -> Assertion+testShow inp out = show inp @?= out  testScientificP :: String -> [(Scientific, String)] -> Assertion testScientificP inp out = readP_to_S Scientific.scientificP inp @?= out