{-# 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 cfg (Criterion act) = withCP65001 $ do
g <- newIORef Nothing
runReaderT act (Crit cfg g)
getGen :: Criterion GenIO
getGen = memoise gen createSystemRandom
memoise :: (Crit -> IORef (Maybe a)) -> IO a -> Criterion a
memoise ref generate = do
r <- Criterion $ asks ref
liftIO $ do
mv <- readIORef r
case mv of
Just rv -> return rv
Nothing -> do
rv <- generate
writeIORef r (Just rv)
return rv