module L04A where -------------------------- -- Instructions for -- Test Data Generation -- Lecture 4A, 2017 -------------------------- import Test.QuickCheck import Data.List(nub) getName = do putStr "Type your name: " name <- getLine return name -- doTwice :: IO t -> IO (t,t) doTwice io = do a <- io b <- io return (a,b) -- types -- * * -- Gen a -- sample, sample' -- arbitrary -- writing generators -- using return, do -- natural numbers nats :: Gen Integer nats = do i <- arbitrary return (abs i) -- evens :: Gen Integer evens :: Gen Integer evens = do i <- arbitrary return (2 * i) -- Building Generators: library functions -- listOf, listOf1, vectorOf -- choose (,) -- return -- oneof -- elements -- frequency -- Example: defining vectorOf using sequence --------------------------------------- -- Example: Lab 2 datatype ------------------------------------------------- data Suit = Spades | Hearts | Diamonds | Clubs deriving (Show,Eq) rSuit :: Gen Suit rSuit = elements [Spades,Hearts, Diamonds, Clubs] -- making an instance instance Arbitrary Suit where arbitrary = rSuit nonprop_Suit s1 s2 = s1 == (s2 :: Suit) data Rank = Numeric Int | Jack | Queen | King | Ace deriving (Eq,Show,Ord) instance Arbitrary Rank where -- arbitrary = frequency [(9,rNumeric),(4,rRoyal)] arbitrary = elements ([Numeric i | i <- [2..10]] ++ [Jack,Queen,King,Ace] ) rNumeric, rRoyal :: Gen Rank rNumeric = do i <- choose(2,10) return (Numeric i) rRoyal = elements [Jack,Queen,King,Ace] prop_rank' r = collect r (prop_rank r) -- datatype invariant; classify (and collect) prop_rank (Numeric n) = n <= 10 && n > 1 prop_rank _ = True data Card = Card Rank Suit deriving (Eq,Show) instance Arbitrary Card where arbitrary = do r <- arbitrary s <- arbitrary return (Card r s) type Hand = [Card] -- no choice of generator data Deck = Deck {cards :: [Card]} deriving (Eq, Show) instance Arbitrary Deck where arbitrary = do cs <- arbitrary return (Deck (nub cs)) prop_deck deck = collect l (l <= 52) where l = length (cards deck) -- alternative: nonempty deck? listof1 -- How to use a different generator than arbitrary? -- (i) use QuickCheck function forAll -- [not covered here: see documentation] -- (ii) Make a new type from the old with its own generator data Poker = Poker Hand deriving Show instance Arbitrary Poker where arbitrary = do cs <- vectorOf 5 arbitrary -- 5 cards return (Poker cs)