Skip to content

Commit ef2ee10

Browse files
committed
Infinities as floating point endpoints
1 parent 11464aa commit ef2ee10

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

src/System/Random/Internal.hs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ runStateGen g f = runState (f StateGenM) g
423423
--
424424
-- >>> import System.Random.Stateful
425425
-- >>> let pureGen = mkStdGen 137
426-
-- >>> runStateGen_ pureGen randomM :: Int
426+
-- >>> runStateGen_ pureGen randomM :: Int
427427
-- 7879794327570578227
428428
--
429429
-- @since 1.2.0
@@ -772,6 +772,9 @@ instance UniformRange Bool where
772772
instance UniformRange Double where
773773
uniformRM (l, h) g
774774
| l == h = return l
775+
| isInfinite l && isInfinite h = return (0/0) -- NaN
776+
| isInfinite l = return l
777+
| isInfinite h = return h
775778
| otherwise = do
776779
x <- uniformDouble01M g
777780
return $ x * l + (1 -x) * h
@@ -806,6 +809,9 @@ uniformDoublePositive01M g = (+ d) <$> uniformDouble01M g
806809
instance UniformRange Float where
807810
uniformRM (l, h) g
808811
| l == h = return l
812+
| isInfinite l && isInfinite h = return (0/0) -- NaN
813+
| isInfinite l = return l
814+
| isInfinite h = return h
809815
| otherwise = do
810816
x <- uniformFloat01M g
811817
return $ x * l + (1 - x) * h

test/Spec.hs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,21 @@ integralSpec px =
126126

127127
floatingSpec ::
128128
forall a.
129-
(SC.Serial IO a, Typeable a, Num a, Ord a, Random a, UniformRange a, Show a)
129+
(SC.Serial IO a, Typeable a, Num a, Ord a, Random a, UniformRange a, Read a, Show a)
130130
=> Proxy a -> TestTree
131131
floatingSpec px =
132132
testGroup ("(" ++ showsType px ")")
133133
[ SC.testProperty "uniformR" $ seeded $ Range.uniformRangeWithin px
134+
, testCase "r = +inf, x = 0" $ positiveInf @?= fst (uniformR (0, positiveInf) (ConstGen 0))
135+
, testCase "r = +inf, x = 1" $ positiveInf @?= fst (uniformR (0, positiveInf) (ConstGen 1))
136+
, testCase "l = -inf, x = 0" $ negativeInf @?= fst (uniformR (negativeInf, 0) (ConstGen 0))
137+
, testCase "l = -inf, x = 1" $ negativeInf @?= fst (uniformR (negativeInf, 0) (ConstGen 1))
134138
-- TODO: Add more tests
135139
]
140+
where
141+
positiveInf, negativeInf :: a
142+
positiveInf = read "Infinity"
143+
negativeInf = read "-Infinity"
136144

137145
runSpec :: TestTree
138146
runSpec = testGroup "runGenState_ and runPrimGenIO_"
@@ -141,3 +149,9 @@ runSpec = testGroup "runGenState_ and runPrimGenIO_"
141149
-- | Create a StdGen instance from an Int and pass it to the given function.
142150
seeded :: (StdGen -> a) -> Int -> a
143151
seeded f = f . mkStdGen
152+
153+
newtype ConstGen = ConstGen Word64
154+
155+
instance RandomGen ConstGen where
156+
genWord64 g@(ConstGen c) = (c, g)
157+
split g = (g, g)

0 commit comments

Comments
 (0)