{-# LANGUAGE Trustworthy #-}
module Criterion.Monad
(
Criterion
, withConfig
, getGen
) where
import Control.Monad.Reader (asks, runReaderT)
import Control.Monad.Trans (liftIO)
import Criterion.Monad.Internal (Criterion(..), Crit(..))
import Criterion.Types hiding (measure)
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
import System.IO.CodePage (withCP65001)
import System.Random.MWC (GenIO, createSystemRandom)
withConfig :: Config -> Criterion a -> IO a
withConfig :: Config -> Criterion a -> IO a
withConfig Config
cfg (Criterion ReaderT Crit IO a
act) = IO a -> IO a
forall a. IO a -> IO a
withCP65001 (IO a -> IO a) -> IO a -> IO a
forall a b. (a -> b) -> a -> b
$ do
IORef (Maybe (Gen RealWorld))
g <- Maybe (Gen RealWorld) -> IO (IORef (Maybe (Gen RealWorld)))
forall a. a -> IO (IORef a)
newIORef Maybe (Gen RealWorld)
forall a. Maybe a
Nothing
ReaderT Crit IO a -> Crit -> IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT Crit IO a
act (Config -> IORef (Maybe GenIO) -> Crit
Crit Config
cfg IORef (Maybe (Gen RealWorld))
IORef (Maybe GenIO)
g)
getGen :: Criterion GenIO
getGen :: Criterion GenIO
getGen = (Crit -> IORef (Maybe (Gen RealWorld)))
-> IO (Gen RealWorld) -> Criterion (Gen RealWorld)
forall a. (Crit -> IORef (Maybe a)) -> IO a -> Criterion a
memoise Crit -> IORef (Maybe (Gen RealWorld))
Crit -> IORef (Maybe GenIO)
gen IO (Gen RealWorld)
IO GenIO
createSystemRandom
memoise :: (Crit -> IORef (Maybe a)) -> IO a -> Criterion a
memoise :: (Crit -> IORef (Maybe a)) -> IO a -> Criterion a
memoise Crit -> IORef (Maybe a)
ref IO a
generate = do
IORef (Maybe a)
r <- ReaderT Crit IO (IORef (Maybe a)) -> Criterion (IORef (Maybe a))
forall a. ReaderT Crit IO a -> Criterion a
Criterion (ReaderT Crit IO (IORef (Maybe a)) -> Criterion (IORef (Maybe a)))
-> ReaderT Crit IO (IORef (Maybe a)) -> Criterion (IORef (Maybe a))
forall a b. (a -> b) -> a -> b
$ (Crit -> IORef (Maybe a)) -> ReaderT Crit IO (IORef (Maybe a))
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Crit -> IORef (Maybe a)
ref
IO a -> Criterion a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> Criterion a) -> IO a -> Criterion a
forall a b. (a -> b) -> a -> b
$ do
Maybe a
mv <- IORef (Maybe a) -> IO (Maybe a)
forall a. IORef a -> IO a
readIORef IORef (Maybe a)
r
case Maybe a
mv of
Just a
rv -> a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
rv
Maybe a
Nothing -> do
a
rv <- IO a
generate
IORef (Maybe a) -> Maybe a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe a)
r (a -> Maybe a
forall a. a -> Maybe a
Just a
rv)
a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
rv