ivory-quickcheck-0.1.0.0: src/Ivory/QuickCheck/Monad.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
-- | Monad for generating random C inputs for Ivory programs.
module Ivory.QuickCheck.Monad
( IvoryGen()
, set
, get
, run
, runIO
) where
import MonadLib hiding (set, get, lift)
import qualified MonadLib as M
import Control.Applicative (Applicative(..))
import qualified System.Random as R
--------------------------------------------------------------------------------
newtype IvoryGen a = IvoryGen (StateT R.StdGen Id a)
deriving (Functor, Applicative, Monad)
set :: R.StdGen -> IvoryGen ()
set = IvoryGen . M.set
-- | Get the current random number, split it, use one and put back the other.
get :: IvoryGen R.StdGen
get = do
rnd <- IvoryGen M.get
let (r0, r1) = R.split rnd
set r1
return r0
run :: R.StdGen -> IvoryGen a -> (a, R.StdGen)
run rnd (IvoryGen st) = runId (runStateT rnd st)
-- | Generate a fresh random value, run the monad with it, and return the
-- result.
runIO :: IvoryGen a -> IO a
runIO igen = do
rnd <- R.newStdGen
let (a,_) = run rnd igen
return a
--------------------------------------------------------------------------------