numhask-hedgehog-0.3: src/NumHask/Hedgehog/Gen.hs
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wall #-}
module NumHask.Hedgehog.Gen
( rational
, rational_
, integral
, integral_
, uniform
, negUniform
, genPair
, genRange
, genRangePos
, genComplex
) where
import Hedgehog as H
import NumHask.Prelude as P
import qualified Hedgehog.Internal.Gen as Gen
import qualified Hedgehog.Internal.Seed as Seed
import qualified Hedgehog.Range as Range
-- * hedgehog rng's are Num instances, so we supply a few of our own
-- There are basically two types of random variates: a discrete Integer type and a continuous rational type
-- | a rational-style random variate
rational :: (ToRatio a, FromRatio a, MonadGen m) => Range.Range a -> m a
rational r =
Gen.generate $ \size seed ->
let
(x, y) =
Range.bounds size r
in
fromRational . fst $
Seed.nextDouble (fromRational x) (fromRational y) seed
-- | an integral-stype random variate
integral :: (ToInteger a, FromInteger a, MonadGen m) => Range.Range a -> m a
integral r =
Gen.generate $ \size seed ->
let
(x, y) =
Range.bounds size r
in
fromIntegral . fst $
Seed.nextInteger (fromIntegral x) (fromIntegral y) seed
-- | an integral-style random variate utilising Bounds
integral_ ::
( Additive a
, Bounded a
, ToInteger a
, FromInteger a
, MonadGen m)
=> m a
integral_ = integral (Range.constantFrom zero minBound maxBound)
-- | a rational style random variate utilising Bounds
rational_ ::
( Additive a
, Bounded a
, ToRatio a
, FromRatio a
, MonadGen m)
=> m a
rational_ = rational (Range.constantFrom zero minBound maxBound)
-- | a uniform distribution between zero and one
uniform ::
( Field a
, ToRatio a
, FromRatio a
, MonadGen m)
=> m a
uniform = rational (Range.constantFrom zero zero one)
-- | a uniform distribution between -1 and 1
negUniform ::
( Field a
, ToRatio a
, FromRatio a
, Subtractive a
, MonadGen m)
=> m a
negUniform = rational (Range.constantFrom zero (negate one) one)
-- | a complex random variate
genComplex :: Monad m => m a -> m (Complex a)
genComplex g = do
r <- g
i <- g
pure (r :+ i)
-- | Space
genRange :: forall a m. (JoinSemiLattice a, MeetSemiLattice a, MonadGen m) => m a -> m (P.Range a)
genRange g = do
a <- g
b <- g
pure (a >.< b)
genRangePos :: forall a m. (JoinSemiLattice a, MeetSemiLattice a, MonadGen m) => m a -> m (P.Range a)
genRangePos g = do
a <- g
b <- g
pure (a ... b)
-- | a pair
genPair :: (Monad m) => m a -> m (Pair a)
genPair g = do
a <- g
b <- g
pure (Pair a b)