quickspec-0.9.6: examples/Arrays.hs
-- Arrays.
{-# LANGUAGE ScopedTypeVariables, FlexibleInstances, DeriveDataTypeable #-}
import Test.QuickCheck
import Test.QuickSpec
import Data.Typeable
import Data.Array
put :: Ix i => i -> a -> Array i a -> Array i a
put ix v arr = arr // [(ix, v)]
arrays :: forall a. (Typeable a, Ord a, Arbitrary a) => a -> [Sig]
arrays a = [
-- Don't include head, or functions on natural numbers---they
-- generate too many irrelevant terms.
prelude (undefined :: a) `without` ["head", "*", "0", "1"],
lists (undefined :: Int) `without` ["head"],
["x", "y", "z"] `vars` (undefined :: a),
["a"] `vars` (undefined :: Array Int a),
-- Generate ranges using a custom generator to improve test data
-- distribution.
["r"] `gvars` genRange,
"!" `fun2` ((!) :: Array Int a -> Int -> a),
"put" `fun3` (put :: Int -> a -> Array Int a -> Array Int a),
"listArray" `fun2` (listArray :: (Int, Int) -> [a] -> Array Int a),
"elems" `fun1` (elems :: Array Int a -> [a]),
"indices" `fun1` (indices :: Array Int a -> [Int])]
instance Arbitrary a => Arbitrary (Array Int a) where
arbitrary = do
(low, high) <- genRange
elems <- arbitrary :: Gen (Int -> Maybe a)
return (array (low, high) [(i, x) | i <- [low..high], Just x <- [elems i]])
genRange :: Gen (Int, Int)
genRange = do
low <- choose (-2, 2)
high <- fmap (low +) (choose (-1, 2))
return (low, high)
-- Use Two instead of A to improve the chance of getting the right test data.
main = quickSpec (arrays (undefined :: Two))