checkers-0.1.1: src/Test/QuickCheck/Instances/List.hs
module Test.QuickCheck.Instances.List
(anyList,nonEmpty
,infiniteList
,setLength
,increasing,nondecreasing
,increasingInf,nondecreasingInf
,decreasing,nonincreasing
,decreasingInf,nonincreasingInf
) where
import Test.QuickCheck
import Test.QuickCheck.Applicative ()
import Test.QuickCheck.Instances.Num
import Control.Applicative
{- | Generates a non-empty list with the contents generated using its
argument.
-}
nonEmpty :: Gen a -> Gen [a]
nonEmpty x = liftA2 (:) x (anyList x)
{- | Generates any list (possibly empty) with the contents generated using
its argument.
-}
anyList :: Gen a -> Gen [a]
anyList x = frequency [(1, pure []), (4, nonEmpty x)]
{- | Generates an infinite list with contents generated using its argument
-}
infiniteList :: Gen a -> Gen [a]
infiniteList x = liftA2 (:) x (infiniteList x)
{- | Generates a list with a set length
-}
setLength :: Int -> Gen a -> Gen [a]
setLength 0 _ = pure []
setLength n g = (:) <$> g <*> setLength (n-1) g
sumA :: (Applicative f, Num a) => f a -> f [a] -> f [a]
sumA = liftA2 (scanl (+))
monotonic_ :: (Arbitrary a, Num a) => (Gen a -> Gen [a]) -> Gen a -> Gen [a]
monotonic_ listGen gen = sumA arbitrary (listGen gen)
-- TODO: Generalise this to Ord a.
monotonic :: (Arbitrary a, Num a) => Gen a -> Gen [a]
monotonic gen = monotonic_ anyList gen
-- | Generate increasing towards infinity
increasing :: (Arbitrary a, Num a) => Gen [a]
increasing = monotonic positive
-- | Generate an infinite list of increasing values
increasingInf :: (Arbitrary a, Num a) => Gen [a]
increasingInf = monotonic_ infiniteList positive
-- | Generate nondecreasing values
nondecreasing :: (Arbitrary a, Num a) => Gen [a]
nondecreasing = monotonic nonNegative
-- | Generate an infinite list of nondecreasing values
nondecreasingInf :: (Arbitrary a, Num a) => Gen [a]
nondecreasingInf = monotonic_ infiniteList nonNegative
-- | Generate increasing towards infinity
decreasing :: (Arbitrary a, Num a) => Gen [a]
decreasing = monotonic negative
-- | Generate an infinite list of increasing values
decreasingInf :: (Arbitrary a, Num a) => Gen [a]
decreasingInf = monotonic_ infiniteList negative
-- | Generate nondecreasing values
nonincreasing :: (Arbitrary a, Num a) => Gen [a]
nonincreasing = monotonic nonPositive
-- | Generate an infinite list of nondecreasing values
nonincreasingInf :: (Arbitrary a, Num a) => Gen [a]
nonincreasingInf = monotonic_ infiniteList nonPositive