Safe Haskell  Safe 

Language  Haskell98 
Allows testing of monadic values. Will generally follow this form:
prop_monadic a b =monadicIO
$ do a' <run
(f a) b' <run
(f b)  ...assert
someBoolean
Example using the FACTOR(1)
commandline utility:
import System.Process import Test.QuickCheck import Test.QuickCheck.Monadic  $ factor 16  16: 2 2 2 2 factor :: Integer > IO [Integer] factor n = parse `fmap`readProcess
"factor" [show n] "" where parse :: String > [Integer] parse = map read . tail . words prop_factor :: Positive Integer > Property prop_factor (Positive
n) =monadicIO
$ do factors <run
(factor n)assert
(product factors == n)
>>>
quickCheck prop_factor
+++ OK, passed 100 tests.
See the paper "Testing Monadic Code with QuickCheck".
 newtype PropertyM m a = MkPropertyM {
 unPropertyM :: (a > Gen (m Property)) > Gen (m Property)
 run :: Monad m => m a > PropertyM m a
 assert :: Monad m => Bool > PropertyM m ()
 pre :: Monad m => Bool > PropertyM m ()
 wp :: Monad m => m a > (a > PropertyM m b) > PropertyM m b
 pick :: (Monad m, Show a) => Gen a > PropertyM m a
 forAllM :: (Monad m, Show a) => Gen a > (a > PropertyM m b) > PropertyM m b
 monitor :: Monad m => (Property > Property) > PropertyM m ()
 stop :: (Testable prop, Monad m) => prop > PropertyM m a
 monadic :: Monad m => (m Property > Property) > PropertyM m a > Property
 monadic' :: Monad m => PropertyM m a > Gen (m Property)
 monadicIO :: PropertyM IO a > Property
 monadicST :: (forall s. PropertyM (ST s) a) > Property
 runSTGen :: (forall s. Gen (ST s a)) > Gen a
Property monad
The property monad is really a monad transformer that can contain
monadic computations in the monad m
it is parameterized by:
m
 them
computations that may be performed withinPropertyM
Elements of PropertyM m a
may mix property operations and m
computations.
MkPropertyM  

Monadic specification combinators
run :: Monad m => m a > PropertyM m a Source
The lifting operation of the property monad. Allows embedding
monadic/IO
actions in properties:
log :: Int > IO () prop_foo n = monadicIO $ do run (log n)  ...
assert :: Monad m => Bool > PropertyM m () Source
Allows embedding nonmonadic properties into monadic ones.
pre :: Monad m => Bool > PropertyM m () Source
Tests preconditions. Unlike assert
this does not cause the
property to fail, rather it discards them just like using the
implication combinator ==>
.
This allows representing the Hoare triple
{p} x ← e{q}
as
pre p x < run e assert q
pick :: (Monad m, Show a) => Gen a > PropertyM m a Source
Quantification in a monadic property, fits better with
donotation than forAllM
.
monitor :: Monad m => (Property > Property) > PropertyM m () Source
Allows making observations about the test data:
monitor (collect
e)
collects the distribution of value of e
.
monitor (counterexample
"Failure!")
Adds "Failure!"
to the counterexamples.
Run functions
monadicIO :: PropertyM IO a > Property Source
Runs the property monad for IO
computations.
prop_cat msg = monadicIO $ do (exitCode, stdout, _) < run (readProcessWithExitCode
"cat" [] msg) pre (ExitSuccess
== exitCode) assert (stdout == msg)
>>>
quickCheck prop_cat
+++ OK, passed 100 tests.
monadicST :: (forall s. PropertyM (ST s) a) > Property Source
Runs the property monad for ST
computations.
 Your mutable sorting algorithm here sortST :: Ord a => [a] >ST
s (MVector s a) sortST =thaw
.fromList
.sort
prop_sortST xs = monadicST $ do sorted < run (freeze
=<< sortST xs) assert (toList
sorted == sort xs)
>>>
quickCheck prop_sortST
+++ OK, passed 100 tests.