{-# 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 --------------------------------------------------------------------------------