exact-real 0.11.3 → 0.12.0
raw patch · 5 files changed
+48/−15 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.CReal.Internal: instance GHC.TypeLits.KnownNat n => System.Random.Random (Data.CReal.Internal.CReal n)
Files
- exact-real.cabal +5/−3
- src/Data/CReal/Internal.hs +16/−0
- test/Data/CReal/Extra.hs +0/−12
- test/Random.hs +22/−0
- test/Test.hs +5/−0
exact-real.cabal view
@@ -1,5 +1,5 @@ name: exact-real-version: 0.11.3+version: 0.12.0 synopsis: Exact real arithmetic description: A type to represent exact real numbers using fast binary Cauchy sequences.@@ -31,7 +31,8 @@ build-depends: base >= 4.8 && < 4.9, integer-gmp < 1.1.0.0,- memoize >= 0.7 && < 0.8+ memoize >= 0.7 && < 0.8,+ random >= 1.0 && < 1.2 hs-source-dirs: src default-language:@@ -75,6 +76,7 @@ Fractional, Num, Ord,+ Random, Read, Real, RealFloat,@@ -90,8 +92,8 @@ tasty-quickcheck >= 0.8 && < 0.9, tasty-hunit >= 0.9 && < 0.10, QuickCheck >= 2.8 && < 2.9,- checkers >= 0.4 && < 0.5, random >= 1.0 && < 1.2,+ checkers >= 0.4 && < 0.5, exact-real test-suite doctest
src/Data/CReal/Internal.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE PostfixOperators #-}+{-# LANGUAGE ScopedTypeVariables #-} ----------------------------------------------------------------------------- -- | This module exports a bunch of utilities for working inside the CReal@@ -64,6 +65,7 @@ import GHC.TypeLits import Numeric (readSigned, readFloat) import Data.Function.Memoize (memoize)+import System.Random (Random(..)) {-# ANN module "HLint: ignore Reduce duplication" #-} @@ -302,6 +304,20 @@ in compare ((x - y) `atPrecision` p) 0 max (CR x) (CR y) = crMemoize (\p -> max (x p) (y p)) min (CR x) (CR y) = crMemoize (\p -> min (x p) (y p))++-- | The 'Random' instance for @\'CReal\' p@ will return random number with at+-- least @p@ digits of precision, every digit after that is zero.+instance KnownNat n => Random (CReal n) where+ randomR (lo, hi) g = let d = hi - lo+ l = 1 + log2 (abs d `atPrecision` 0)+ p = l + crealPrecision lo+ (n, g') = randomR (0, 2^p) g+ r = fromRational (n % 2^p)+ in (r * d + lo, g')+ random g = let p = 1 + crealPrecision (undefined :: CReal n)+ (n, g') = randomR (0, max 0 (2^p - 2)) g+ r = fromRational (n % 2^p)+ in (r, g') -------------------------------------------------------------------------------- -- Some utility functions
test/Data/CReal/Extra.hs view
@@ -5,10 +5,7 @@ ) where import Data.CReal-import Data.CReal.Internal (log2)-import Data.Ratio ((%)) import GHC.TypeLits-import System.Random (Random(..)) import Test.QuickCheck (Arbitrary(..), choose) import Test.QuickCheck.Checkers (EqProp(..), eq) @@ -20,13 +17,4 @@ integralPart <- fromInteger <$> arbitrary fractionalPart <- choose (-0.5, 0.5) pure (integralPart + fractionalPart)--instance KnownNat n => Random (CReal n) where- randomR (lo, hi) g = let d = hi - lo- l = 1 + log2 (abs d `atPrecision` 0)- p = l + crealPrecision lo- (n, g') = randomR (0, 2^p) g- r = fromRational (n % 2^p)- in (r * d + lo, g')- random = randomR (0, 1)
+ test/Random.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE ScopedTypeVariables #-}++module Random+ ( random+ ) where++import Test.Tasty (testGroup, TestTree)+import Test.Tasty.QuickCheck (testProperty, Arbitrary, (==>))+import System.Random (Random, randoms, randomRs, mkStdGen)++random :: forall a. (Arbitrary a, Show a, Ord a, Fractional a, Random a) => a -> TestTree+random _ = testGroup "Test Random instance" ts+ where ts = [ testProperty "randomR range"+ (\s l u -> let rs = take 100 (randomRs (l :: a, u) (mkStdGen s))+ in l <= u ==> (all (>= l) rs && all (<= u) rs))+ , testProperty "randomR zero bounds"+ (\s l -> let rs = take 100 (randomRs (l :: a, l) (mkStdGen s))+ in all (== l) rs)+ , testProperty "random range"+ (\s -> let rs = take 100 (randoms (mkStdGen s)) :: [a]+ in all (>= 0) rs && all (< 1) rs)+ ]
test/Test.hs view
@@ -24,6 +24,7 @@ import Real (real) import RealFrac (realFrac) import RealFloat (realFloat)+import Random (random) -- How many binary digits to use for comparisons TODO: Test with many different -- precisions@@ -52,6 +53,10 @@ {-# ANN test_read "HLint: ignore Use camelCase" #-} test_read :: [TestTree] test_read = [ read' (undefined :: CReal Precision) ]++{-# ANN test_random "HLint: ignore Use camelCase" #-}+test_random :: [TestTree]+test_random = [ random (undefined :: CReal Precision) ] prop_decimalDigits :: Positive Int -> Property prop_decimalDigits (Positive p) = let d = decimalDigitsAtPrecision p