{-# LANGUAGE RankNTypes #-}

module Ouroboros.Network.Testing.QuickCheck
  ( runSimGen
  , monadicSim
  ) where

import           Test.QuickCheck
import           Test.QuickCheck.Gen.Unsafe (Capture (..), capture)
import           Test.QuickCheck.Monadic

import           Control.Monad.IOSim

-- | 'IOSim' analogue of 'runSTGen'
--
-- > runSTGen  :: (forall s. Gen (ST    s a)) -> Gen a
-- > runSimGen :: (forall s. Gen (IOSim s a)) -> Gen a
runSimGen :: (forall s. Gen (IOSim s a)) -> Gen a
runSimGen :: (forall s. Gen (IOSim s a)) -> Gen a
runSimGen forall s. Gen (IOSim s a)
f = do
    Capture forall a. Gen a -> a
eval <- Gen Capture
capture
    a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Gen a) -> a -> Gen a
forall a b. (a -> b) -> a -> b
$ (forall s. IOSim s a) -> a
forall a. (forall s. IOSim s a) -> a
runSimOrThrow (Gen (IOSim s a) -> IOSim s a
forall a. Gen a -> a
eval Gen (IOSim s a)
forall s. Gen (IOSim s a)
f)

-- | 'IOSim' analogue of 'monadicST'
--
-- > monadicST  :: Testable a => (forall s. PropertyM (ST    s) a) -> Property
-- > monadicSim :: Testable a => (forall s. PropertyM (IOSim s) a) -> Property
monadicSim :: Testable a => (forall s. PropertyM (IOSim s) a) -> Property
monadicSim :: (forall s. PropertyM (IOSim s) a) -> Property
monadicSim forall s. PropertyM (IOSim s) a
m = Gen Property -> Property
forall prop. Testable prop => prop -> Property
property ((forall s. Gen (IOSim s Property)) -> Gen Property
forall a. (forall s. Gen (IOSim s a)) -> Gen a
runSimGen (PropertyM (IOSim s) a -> Gen (IOSim s Property)
forall a (m :: * -> *).
(Testable a, Monad m) =>
PropertyM m a -> Gen (m Property)
monadic' PropertyM (IOSim s) a
forall s. PropertyM (IOSim s) a
m))