module Data.Random.Source.PureMT where
import Data.Random.Internal.Primitives
import Data.Random.Source
import System.Random.Mersenne.Pure64
import Data.StateRef
import Control.Monad.Prompt
import Control.Monad.State
import qualified Control.Monad.ST.Strict as S
import qualified Control.Monad.State.Strict as S
getRandomPrimFromMTRef :: (Monad m, ModifyRef sr m PureMT) => sr -> Prim a -> m a
getRandomPrimFromMTRef ref prim
| supported prim = getThing (genPrim prim)
| otherwise = runPromptM (getRandomPrimFromMTRef ref) (decomposePrimWhere supported prim)
where
supported :: Prim a -> Bool
supported PrimWord64 = True
supported PrimDouble = True
supported _ = False
genPrim :: Prim a -> (PureMT -> (a, PureMT))
genPrim PrimWord64 = randomWord64
genPrim PrimDouble = randomDouble
genPrim p = error ("getRandomPrimFromMTRef: genPrim called for unsupported prim " ++ show p)
getThing thing = atomicModifyReference ref $ \(!oldMT) -> case thing oldMT of (!w, !newMT) -> (newMT, w)
getRandomPrimFromMTState :: MonadState PureMT m => Prim a -> m a
getRandomPrimFromMTState prim
| supported prim = getThing (genPrim prim)
| otherwise = runPromptM getRandomPrimFromMTState (decomposePrimWhere supported prim)
where
supported :: Prim a -> Bool
supported PrimWord64 = True
supported PrimDouble = True
supported _ = False
genPrim :: Prim a -> (PureMT -> (a, PureMT))
genPrim PrimWord64 = randomWord64
genPrim PrimDouble = randomDouble
genPrim p = error ("getRandomPrimFromMTRef: genPrim called for unsupported prim " ++ show p)
getThing thing = do
!mt <- get
let (!ws, !newMt) = thing mt
put newMt
return ws
instance MonadRandom (State PureMT) where
supportedPrims _ _ = True
getSupportedRandomPrim = getRandomPrimFromMTState
instance MonadRandom (S.State PureMT) where
supportedPrims _ _ = True
getSupportedRandomPrim = getRandomPrimFromMTState
instance (Monad m1, ModifyRef (Ref m2 PureMT) m1 PureMT) => RandomSource m1 (Ref m2 PureMT) where
supportedPrimsFrom _ _ = True
getSupportedRandomPrimFrom = getRandomPrimFromMTRef
instance Monad m => MonadRandom (StateT PureMT m) where
supportedPrims _ _ = True
getSupportedRandomPrim = getRandomPrimFromMTState
instance Monad m => MonadRandom (S.StateT PureMT m) where
supportedPrims _ _ = True
getSupportedRandomPrim = getRandomPrimFromMTState
instance (Monad m, ModifyRef (IORef PureMT) m PureMT) => RandomSource m (IORef PureMT) where
supportedPrimsFrom _ _ = True
getSupportedRandomPrimFrom = getRandomPrimFromMTRef
instance (Monad m, ModifyRef (STRef s PureMT) m PureMT) => RandomSource m (STRef s PureMT) where
supportedPrimsFrom _ _ = True
getSupportedRandomPrimFrom = getRandomPrimFromMTRef