Skip to content

Commit

Permalink
Implement safetey around non-splittable PRNGs
Browse files Browse the repository at this point in the history
  • Loading branch information
lehins committed Jan 27, 2021
1 parent 46a15af commit 70cbb62
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 5 deletions.
10 changes: 6 additions & 4 deletions src/System/Random/Internal.hs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash #-}
Expand All @@ -18,7 +19,6 @@
{-# LANGUAGE TypeFamilyDependencies #-}
#else
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE KindSignatures #-}
#endif
{-# OPTIONS_HADDOCK hide, not-home #-}

Expand Down Expand Up @@ -109,6 +109,8 @@ import Data.ByteString (ByteString)
{-# DEPRECATED next "No longer used" #-}
{-# DEPRECATED genRange "No longer used" #-}
class RandomGen g where
type Splittable g :: Bool
type Splittable g = 'True
{-# MINIMAL split,(genWord32|genWord64|(next,genRange)) #-}
-- | Returns an 'Int' that is uniformly distributed over the range returned by
-- 'genRange' (including both end points), and a new generator. Using 'next'
Expand Down Expand Up @@ -194,7 +196,7 @@ class RandomGen g where
-- are not correlated. Some pseudo-random number generators are not
-- splittable. In that case, the 'split' implementation should fail with a
-- descriptive 'error' message.
split :: g -> (g, g)
split :: Splittable g ~ 'True => g -> (g, g)


-- | 'StatefulGen' is an interface to monadic pseudo-random number generators.
Expand Down Expand Up @@ -405,7 +407,7 @@ instance (RandomGen g, MonadState g m) => FrozenGen (StateGen g) m where
-- one of the resulting generators and returns the other.
--
-- @since 1.2.0
splitGen :: (MonadState g m, RandomGen g) => m g
splitGen :: (MonadState g m, RandomGen g, Splittable g ~ 'True) => m g
splitGen = state split

-- | Runs a monadic generating action in the `State` monad using a pure
Expand Down
3 changes: 2 additions & 1 deletion src/System/Random/Stateful.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Expand Down Expand Up @@ -209,7 +210,7 @@ class (RandomGen r, StatefulGen g m) => RandomGenM g r m | g -> r where
-- wrapper with one of the resulting generators and returns the other.
--
-- @since 1.2.0
splitGenM :: RandomGenM g r m => g -> m r
splitGenM :: (Splittable r ~ 'True, RandomGenM g r m) => g -> m r
splitGenM = applyRandomGenM split

instance (RandomGen r, MonadIO m) => RandomGenM (IOGenM r) r m where
Expand Down

0 comments on commit 70cbb62

Please sign in to comment.