{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
-- | Support for generation of __non cryptographically secure__ random numbers
-- for testing purposes.
module Crypto.RNG.Unsafe
  ( -- * CryptoRNG class
    module Crypto.RNG.Class
    -- * Monad transformer for carrying rng state
  , RNGT
  , mapRNGT
  , runRNGT
  , withRNGState
    -- * Instantiation of the initial RNG state
  , RNGState
  , newRNGState
    -- ** Low-level utils
  , withRNG
  ) where

import Control.Applicative
import Control.Concurrent
import Control.Monad
import Control.Monad.Base
import Control.Monad.Catch
import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.Trans.Control
import qualified System.Random as R

import Crypto.RNG.Class

-- | The random number generator state.
newtype RNGState = RNGState (MVar R.StdGen)

-- | Create a new 'RNGState' with a given seed.
newRNGState :: MonadIO m => Int -> m RNGState
newRNGState :: Int -> m RNGState
newRNGState Int
seed = IO RNGState -> m RNGState
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO RNGState -> m RNGState) -> IO RNGState -> m RNGState
forall a b. (a -> b) -> a -> b
$ do
  MVar StdGen -> RNGState
RNGState (MVar StdGen -> RNGState) -> IO (MVar StdGen) -> IO RNGState
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StdGen -> IO (MVar StdGen)
forall a. a -> IO (MVar a)
newMVar (Int -> StdGen
R.mkStdGen Int
seed)

----------------------------------------

-- | Monad transformer with RNG state.
newtype RNGT m a = RNGT { RNGT m a -> ReaderT RNGState m a
unRNGT :: ReaderT RNGState m a }
  deriving ( Applicative (RNGT m)
RNGT m a
Applicative (RNGT m)
-> (forall a. RNGT m a)
-> (forall a. RNGT m a -> RNGT m a -> RNGT m a)
-> (forall a. RNGT m a -> RNGT m [a])
-> (forall a. RNGT m a -> RNGT m [a])
-> Alternative (RNGT m)
RNGT m a -> RNGT m a -> RNGT m a
RNGT m a -> RNGT m [a]
RNGT m a -> RNGT m [a]
forall a. RNGT m a
forall a. RNGT m a -> RNGT m [a]
forall a. RNGT m a -> RNGT m a -> RNGT m a
forall (f :: * -> *).
Applicative f
-> (forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
forall (m :: * -> *). Alternative m => Applicative (RNGT m)
forall (m :: * -> *) a. Alternative m => RNGT m a
forall (m :: * -> *) a. Alternative m => RNGT m a -> RNGT m [a]
forall (m :: * -> *) a.
Alternative m =>
RNGT m a -> RNGT m a -> RNGT m a
many :: RNGT m a -> RNGT m [a]
$cmany :: forall (m :: * -> *) a. Alternative m => RNGT m a -> RNGT m [a]
some :: RNGT m a -> RNGT m [a]
$csome :: forall (m :: * -> *) a. Alternative m => RNGT m a -> RNGT m [a]
<|> :: RNGT m a -> RNGT m a -> RNGT m a
$c<|> :: forall (m :: * -> *) a.
Alternative m =>
RNGT m a -> RNGT m a -> RNGT m a
empty :: RNGT m a
$cempty :: forall (m :: * -> *) a. Alternative m => RNGT m a
$cp1Alternative :: forall (m :: * -> *). Alternative m => Applicative (RNGT m)
Alternative, Functor (RNGT m)
a -> RNGT m a
Functor (RNGT m)
-> (forall a. a -> RNGT m a)
-> (forall a b. RNGT m (a -> b) -> RNGT m a -> RNGT m b)
-> (forall a b c.
    (a -> b -> c) -> RNGT m a -> RNGT m b -> RNGT m c)
-> (forall a b. RNGT m a -> RNGT m b -> RNGT m b)
-> (forall a b. RNGT m a -> RNGT m b -> RNGT m a)
-> Applicative (RNGT m)
RNGT m a -> RNGT m b -> RNGT m b
RNGT m a -> RNGT m b -> RNGT m a
RNGT m (a -> b) -> RNGT m a -> RNGT m b
(a -> b -> c) -> RNGT m a -> RNGT m b -> RNGT m c
forall a. a -> RNGT m a
forall a b. RNGT m a -> RNGT m b -> RNGT m a
forall a b. RNGT m a -> RNGT m b -> RNGT m b
forall a b. RNGT m (a -> b) -> RNGT m a -> RNGT m b
forall a b c. (a -> b -> c) -> RNGT m a -> RNGT m b -> RNGT m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (RNGT m)
forall (m :: * -> *) a. Applicative m => a -> RNGT m a
forall (m :: * -> *) a b.
Applicative m =>
RNGT m a -> RNGT m b -> RNGT m a
forall (m :: * -> *) a b.
Applicative m =>
RNGT m a -> RNGT m b -> RNGT m b
forall (m :: * -> *) a b.
Applicative m =>
RNGT m (a -> b) -> RNGT m a -> RNGT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> RNGT m a -> RNGT m b -> RNGT m c
<* :: RNGT m a -> RNGT m b -> RNGT m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
RNGT m a -> RNGT m b -> RNGT m a
*> :: RNGT m a -> RNGT m b -> RNGT m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
RNGT m a -> RNGT m b -> RNGT m b
liftA2 :: (a -> b -> c) -> RNGT m a -> RNGT m b -> RNGT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> RNGT m a -> RNGT m b -> RNGT m c
<*> :: RNGT m (a -> b) -> RNGT m a -> RNGT m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
RNGT m (a -> b) -> RNGT m a -> RNGT m b
pure :: a -> RNGT m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> RNGT m a
$cp1Applicative :: forall (m :: * -> *). Applicative m => Functor (RNGT m)
Applicative, a -> RNGT m b -> RNGT m a
(a -> b) -> RNGT m a -> RNGT m b
(forall a b. (a -> b) -> RNGT m a -> RNGT m b)
-> (forall a b. a -> RNGT m b -> RNGT m a) -> Functor (RNGT m)
forall a b. a -> RNGT m b -> RNGT m a
forall a b. (a -> b) -> RNGT m a -> RNGT m b
forall (m :: * -> *) a b. Functor m => a -> RNGT m b -> RNGT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> RNGT m a -> RNGT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> RNGT m b -> RNGT m a
$c<$ :: forall (m :: * -> *) a b. Functor m => a -> RNGT m b -> RNGT m a
fmap :: (a -> b) -> RNGT m a -> RNGT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> RNGT m a -> RNGT m b
Functor, Applicative (RNGT m)
a -> RNGT m a
Applicative (RNGT m)
-> (forall a b. RNGT m a -> (a -> RNGT m b) -> RNGT m b)
-> (forall a b. RNGT m a -> RNGT m b -> RNGT m b)
-> (forall a. a -> RNGT m a)
-> Monad (RNGT m)
RNGT m a -> (a -> RNGT m b) -> RNGT m b
RNGT m a -> RNGT m b -> RNGT m b
forall a. a -> RNGT m a
forall a b. RNGT m a -> RNGT m b -> RNGT m b
forall a b. RNGT m a -> (a -> RNGT m b) -> RNGT m b
forall (m :: * -> *). Monad m => Applicative (RNGT m)
forall (m :: * -> *) a. Monad m => a -> RNGT m a
forall (m :: * -> *) a b.
Monad m =>
RNGT m a -> RNGT m b -> RNGT m b
forall (m :: * -> *) a b.
Monad m =>
RNGT m a -> (a -> RNGT m b) -> RNGT m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> RNGT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> RNGT m a
>> :: RNGT m a -> RNGT m b -> RNGT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
RNGT m a -> RNGT m b -> RNGT m b
>>= :: RNGT m a -> (a -> RNGT m b) -> RNGT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
RNGT m a -> (a -> RNGT m b) -> RNGT m b
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (RNGT m)
Monad, Monad (RNGT m)
Monad (RNGT m)
-> (forall a. String -> RNGT m a) -> MonadFail (RNGT m)
String -> RNGT m a
forall a. String -> RNGT m a
forall (m :: * -> *).
Monad m -> (forall a. String -> m a) -> MonadFail m
forall (m :: * -> *). MonadFail m => Monad (RNGT m)
forall (m :: * -> *) a. MonadFail m => String -> RNGT m a
fail :: String -> RNGT m a
$cfail :: forall (m :: * -> *) a. MonadFail m => String -> RNGT m a
$cp1MonadFail :: forall (m :: * -> *). MonadFail m => Monad (RNGT m)
MonadFail, Monad (RNGT m)
Alternative (RNGT m)
RNGT m a
Alternative (RNGT m)
-> Monad (RNGT m)
-> (forall a. RNGT m a)
-> (forall a. RNGT m a -> RNGT m a -> RNGT m a)
-> MonadPlus (RNGT m)
RNGT m a -> RNGT m a -> RNGT m a
forall a. RNGT m a
forall a. RNGT m a -> RNGT m a -> RNGT m a
forall (m :: * -> *).
Alternative m
-> Monad m
-> (forall a. m a)
-> (forall a. m a -> m a -> m a)
-> MonadPlus m
forall (m :: * -> *). MonadPlus m => Monad (RNGT m)
forall (m :: * -> *). MonadPlus m => Alternative (RNGT m)
forall (m :: * -> *) a. MonadPlus m => RNGT m a
forall (m :: * -> *) a.
MonadPlus m =>
RNGT m a -> RNGT m a -> RNGT m a
mplus :: RNGT m a -> RNGT m a -> RNGT m a
$cmplus :: forall (m :: * -> *) a.
MonadPlus m =>
RNGT m a -> RNGT m a -> RNGT m a
mzero :: RNGT m a
$cmzero :: forall (m :: * -> *) a. MonadPlus m => RNGT m a
$cp2MonadPlus :: forall (m :: * -> *). MonadPlus m => Monad (RNGT m)
$cp1MonadPlus :: forall (m :: * -> *). MonadPlus m => Alternative (RNGT m)
MonadPlus
           , MonadError e, Monad (RNGT m)
Monad (RNGT m) -> (forall a. IO a -> RNGT m a) -> MonadIO (RNGT m)
IO a -> RNGT m a
forall a. IO a -> RNGT m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (RNGT m)
forall (m :: * -> *) a. MonadIO m => IO a -> RNGT m a
liftIO :: IO a -> RNGT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> RNGT m a
$cp1MonadIO :: forall (m :: * -> *). MonadIO m => Monad (RNGT m)
MonadIO, MonadBase b, MonadBaseControl b
           , Monad (RNGT m)
e -> RNGT m a
Monad (RNGT m)
-> (forall e a. Exception e => e -> RNGT m a)
-> MonadThrow (RNGT m)
forall e a. Exception e => e -> RNGT m a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
forall (m :: * -> *). MonadThrow m => Monad (RNGT m)
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> RNGT m a
throwM :: e -> RNGT m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> RNGT m a
$cp1MonadThrow :: forall (m :: * -> *). MonadThrow m => Monad (RNGT m)
MonadThrow, MonadThrow (RNGT m)
MonadThrow (RNGT m)
-> (forall e a.
    Exception e =>
    RNGT m a -> (e -> RNGT m a) -> RNGT m a)
-> MonadCatch (RNGT m)
RNGT m a -> (e -> RNGT m a) -> RNGT m a
forall e a. Exception e => RNGT m a -> (e -> RNGT m a) -> RNGT m a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
forall (m :: * -> *). MonadCatch m => MonadThrow (RNGT m)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
RNGT m a -> (e -> RNGT m a) -> RNGT m a
catch :: RNGT m a -> (e -> RNGT m a) -> RNGT m a
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
RNGT m a -> (e -> RNGT m a) -> RNGT m a
$cp1MonadCatch :: forall (m :: * -> *). MonadCatch m => MonadThrow (RNGT m)
MonadCatch, MonadCatch (RNGT m)
MonadCatch (RNGT m)
-> (forall b.
    ((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b)
-> (forall b.
    ((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b)
-> (forall a b c.
    RNGT m a
    -> (a -> ExitCase b -> RNGT m c)
    -> (a -> RNGT m b)
    -> RNGT m (b, c))
-> MonadMask (RNGT m)
RNGT m a
-> (a -> ExitCase b -> RNGT m c)
-> (a -> RNGT m b)
-> RNGT m (b, c)
((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b
((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b
forall b.
((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b
forall a b c.
RNGT m a
-> (a -> ExitCase b -> RNGT m c)
-> (a -> RNGT m b)
-> RNGT m (b, c)
forall (m :: * -> *).
MonadCatch m
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
    m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
forall (m :: * -> *). MonadMask m => MonadCatch (RNGT m)
forall (m :: * -> *) b.
MonadMask m =>
((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b
forall (m :: * -> *) a b c.
MonadMask m =>
RNGT m a
-> (a -> ExitCase b -> RNGT m c)
-> (a -> RNGT m b)
-> RNGT m (b, c)
generalBracket :: RNGT m a
-> (a -> ExitCase b -> RNGT m c)
-> (a -> RNGT m b)
-> RNGT m (b, c)
$cgeneralBracket :: forall (m :: * -> *) a b c.
MonadMask m =>
RNGT m a
-> (a -> ExitCase b -> RNGT m c)
-> (a -> RNGT m b)
-> RNGT m (b, c)
uninterruptibleMask :: ((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b
$cuninterruptibleMask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b
mask :: ((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b
$cmask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. RNGT m a -> RNGT m a) -> RNGT m b) -> RNGT m b
$cp1MonadMask :: forall (m :: * -> *). MonadMask m => MonadCatch (RNGT m)
MonadMask
           , m a -> RNGT m a
(forall (m :: * -> *) a. Monad m => m a -> RNGT m a)
-> MonadTrans RNGT
forall (m :: * -> *) a. Monad m => m a -> RNGT m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: m a -> RNGT m a
$clift :: forall (m :: * -> *) a. Monad m => m a -> RNGT m a
MonadTrans, MonadTrans RNGT
m (StT RNGT a) -> RNGT m a
MonadTrans RNGT
-> (forall (m :: * -> *) a.
    Monad m =>
    (Run RNGT -> m a) -> RNGT m a)
-> (forall (m :: * -> *) a. Monad m => m (StT RNGT a) -> RNGT m a)
-> MonadTransControl RNGT
(Run RNGT -> m a) -> RNGT m a
forall (m :: * -> *) a. Monad m => m (StT RNGT a) -> RNGT m a
forall (m :: * -> *) a. Monad m => (Run RNGT -> m a) -> RNGT m a
forall (t :: (* -> *) -> * -> *).
MonadTrans t
-> (forall (m :: * -> *) a. Monad m => (Run t -> m a) -> t m a)
-> (forall (m :: * -> *) a. Monad m => m (StT t a) -> t m a)
-> MonadTransControl t
restoreT :: m (StT RNGT a) -> RNGT m a
$crestoreT :: forall (m :: * -> *) a. Monad m => m (StT RNGT a) -> RNGT m a
liftWith :: (Run RNGT -> m a) -> RNGT m a
$cliftWith :: forall (m :: * -> *) a. Monad m => (Run RNGT -> m a) -> RNGT m a
$cp1MonadTransControl :: MonadTrans RNGT
MonadTransControl
           )

mapRNGT :: (m a -> n b) -> RNGT m a -> RNGT n b
mapRNGT :: (m a -> n b) -> RNGT m a -> RNGT n b
mapRNGT m a -> n b
f RNGT m a
m = (RNGState -> n b) -> RNGT n b
forall (m :: * -> *) a. (RNGState -> m a) -> RNGT m a
withRNGState ((RNGState -> n b) -> RNGT n b) -> (RNGState -> n b) -> RNGT n b
forall a b. (a -> b) -> a -> b
$ \RNGState
rng -> m a -> n b
f (RNGState -> RNGT m a -> m a
forall (m :: * -> *) a. RNGState -> RNGT m a -> m a
runRNGT RNGState
rng RNGT m a
m)

runRNGT :: RNGState -> RNGT m a -> m a
runRNGT :: RNGState -> RNGT m a -> m a
runRNGT RNGState
rng RNGT m a
m = ReaderT RNGState m a -> RNGState -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (RNGT m a -> ReaderT RNGState m a
forall (m :: * -> *) a. RNGT m a -> ReaderT RNGState m a
unRNGT RNGT m a
m) RNGState
rng

withRNGState :: (RNGState -> m a) -> RNGT m a
withRNGState :: (RNGState -> m a) -> RNGT m a
withRNGState = ReaderT RNGState m a -> RNGT m a
forall (m :: * -> *) a. ReaderT RNGState m a -> RNGT m a
RNGT (ReaderT RNGState m a -> RNGT m a)
-> ((RNGState -> m a) -> ReaderT RNGState m a)
-> (RNGState -> m a)
-> RNGT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RNGState -> m a) -> ReaderT RNGState m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT

instance MonadIO m => CryptoRNG (RNGT m) where
  randomBytes :: Int -> RNGT m ByteString
randomBytes Int
n  = ReaderT RNGState m RNGState -> RNGT m RNGState
forall (m :: * -> *) a. ReaderT RNGState m a -> RNGT m a
RNGT ReaderT RNGState m RNGState
forall r (m :: * -> *). MonadReader r m => m r
ask RNGT m RNGState
-> (RNGState -> RNGT m ByteString) -> RNGT m ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (RNGState -> (StdGen -> (ByteString, StdGen)) -> RNGT m ByteString
forall (m :: * -> *) a.
MonadIO m =>
RNGState -> (StdGen -> (a, StdGen)) -> m a
`withRNG` \StdGen
g -> Int -> StdGen -> (ByteString, StdGen)
forall g. RandomGen g => Int -> g -> (ByteString, g)
R.genByteString Int
n StdGen
g)
  random :: RNGT m a
random         = ReaderT RNGState m RNGState -> RNGT m RNGState
forall (m :: * -> *) a. ReaderT RNGState m a -> RNGT m a
RNGT ReaderT RNGState m RNGState
forall r (m :: * -> *). MonadReader r m => m r
ask RNGT m RNGState -> (RNGState -> RNGT m a) -> RNGT m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (RNGState -> (StdGen -> (a, StdGen)) -> RNGT m a
forall (m :: * -> *) a.
MonadIO m =>
RNGState -> (StdGen -> (a, StdGen)) -> m a
`withRNG` \StdGen
g -> StdGen -> (a, StdGen)
forall g a. (RandomGen g, Uniform a) => g -> (a, g)
R.uniform StdGen
g)
  randomR :: (a, a) -> RNGT m a
randomR (a, a)
bounds = ReaderT RNGState m RNGState -> RNGT m RNGState
forall (m :: * -> *) a. ReaderT RNGState m a -> RNGT m a
RNGT ReaderT RNGState m RNGState
forall r (m :: * -> *). MonadReader r m => m r
ask RNGT m RNGState -> (RNGState -> RNGT m a) -> RNGT m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (RNGState -> (StdGen -> (a, StdGen)) -> RNGT m a
forall (m :: * -> *) a.
MonadIO m =>
RNGState -> (StdGen -> (a, StdGen)) -> m a
`withRNG` \StdGen
g -> (a, a) -> StdGen -> (a, StdGen)
forall g a. (RandomGen g, UniformRange a) => (a, a) -> g -> (a, g)
R.uniformR (a, a)
bounds StdGen
g)

withRNG :: MonadIO m => RNGState -> (R.StdGen -> (a, R.StdGen)) -> m a
withRNG :: RNGState -> (StdGen -> (a, StdGen)) -> m a
withRNG (RNGState MVar StdGen
rng) StdGen -> (a, StdGen)
f = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a)
-> ((StdGen -> IO (StdGen, a)) -> IO a)
-> (StdGen -> IO (StdGen, a))
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar StdGen -> (StdGen -> IO (StdGen, a)) -> IO a
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar MVar StdGen
rng ((StdGen -> IO (StdGen, a)) -> m a)
-> (StdGen -> IO (StdGen, a)) -> m a
forall a b. (a -> b) -> a -> b
$ \StdGen
g -> do
  (a
a, StdGen
newG) <- (a, StdGen) -> IO (a, StdGen)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a, StdGen) -> IO (a, StdGen)) -> (a, StdGen) -> IO (a, StdGen)
forall a b. (a -> b) -> a -> b
$ StdGen -> (a, StdGen)
f StdGen
g
  StdGen
newG StdGen -> IO (StdGen, a) -> IO (StdGen, a)
`seq` (StdGen, a) -> IO (StdGen, a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (StdGen
newG, a
a)