IO
putStr :: String -> IO () getLine :: IO String writeFile :: FilePath -> String -> IO () readFile :: FilePath -> IO String
do
copyFile :: FilePath -> FilePath -> IO () copyFile from to = do text <- readFile from writeFile to text
prop_example :: Integer -> Bool prop_example n = (n+3)^2 == n^2 + 6*n + 9
quickCheck prop_example
+++ OK, passed 100 tests.
Gen a
arbitrary :: Arbitrary a => Gen a
sample :: Show a => Gen a -> IO () sample' :: Gen a -> IO [a] generate :: Gen a -> IO a
sample' (arbitrary::Gen Integer)
[0,2,-1,-6,2,4,4,-11,14,9,3]
sample' (arbitrary::Gen Integer)
[0,2,-2,-3,5,4,-9,-5,16,-13,-6]
sample' (arbitrary::Gen Bool)
[True,False,True,False,False,True,True,False,False,True,True]
sample (arbitrary::Gen [Integer])
[]
[2]
[-3]
[4]
[7,-2,-3,-8,5,8,-5]
[3,-4]
[-10,0,7,1,2,5,-12,-3,8,-7,10,11]
[-2,3,-5,-8,-3,-2,14,6,1,6,7,-2,-3,-12]
[15,-13,15,-11,-11,-6,13,16,7,-13,-8,-2,-13,13,3,-13]
[5,-15,5,13,12,1,-3,4,-13,-15,-7,18,-9,-18]
[-8,-20,-10,-4,6,5,-15]
elements :: [a] -> Gen a oneof :: [Gen a] -> Gen a frequency :: [(Int,Gen a)] -> Gen a listOf :: Gen a -> Gen [a] vectorOf :: Int -> Gen a -> Gen [a] choose :: Random a => (a,a) -> Gen a
choose
System.Random
.
choose
listOf
sample' (choose ('a','z'))
"ozlikagbygw"
sample' (listOf (choose ('a','z')))
["","t","xviy","","hfpkft","","iiisswjvrkg","suoz","slfosefhofpgla","","l"]
Suit
?
data Suit = Spades | Hearts | Diamonds | Clubs deriving (Eq,Show)
elements
rSuit :: Gen Suit rSuit = elements [Spades,Hearts,Diamonds,Clubs]
Rank
?
data Rank = Numeric Integer | Jack | Queen | King | Ace deriving (Eq,Show)
elements
rNumeric :: Gen Rank rNumeric = elements [Numeric n|n<-[2..10]] rFaceCard :: Gen Rank rFaceCard = elements [Jack,Queen,King,Ace] rRank_v1 :: Gen Rank rRank_v1 = oneof [rNumeric,rFaceCard] rRank :: Gen Rank rRank = frequency [(9,rNumeric),(4,rFaceCard)]
rRank_v1
rRank
Card
data Card = Card Rank Suit deriving (Eq,Show)
rCard :: Gen Card rCard = (??)
rSuit
rRank
Gen a
a
IO a
a
do
rCard :: Gen Card rCard = do r <- rRank s <- rSuit return (Card r s)
do
return
Gen a
IO a
sample' (return 5::Gen Integer)
[5,5,5,5,5,5,5,5,5,5,5]
doTwice
sample' (doTwice (arbitrary::Gen Integer))
[(0,0),(2,-1),(1,1),(6,1),(-4,-1),(4,0),
(-1,7),(4,11),(10,8),(18,-5),(11,14)]
evenInteger :: Gen Integer
evenInteger = do n <- arbitrary
return (2*n)
nonNegative :: Gen Integer
nonNegative = do n <- arbitrary
return (abs n)
sample' evenInteger
[0,2,-4,0,-2,6,-10,-22,22,-2,18]
sample' nonNegative
[0,1,0,3,2,0,1,9,8,2,20]
Hand
?
data Hand = Empty | Add Card Hand deriving (Eq,Show)
rHand :: Gen Hand rHand = oneof [return Empty, do c <- rCard h <- rHand return (Add c h)]
rHand
Rank
validRank :: Rank -> Bool validRank (Numeric n) = 2<=n && n<=10 validRank _ = True
validRank
rRank
forAll
prop_all_validRank_1 = forAll rRank validRank
arbitrary
instance Arbitrary Rank where arbitrary = rRank prop_all_validRank_2 r = validRank r
class Arbitrary where arbitrary :: Gen a shrink :: a -> [a]
instance Arbitrary Bool
instance Arbitrary Int
instance Arbitrary Integer
-- many more instances...
forAll
prop_all_validRank_3 r = collect r (validRank r)
quickCheck prop_all_validRank_3
+++ OK, passed 100 tests:
12% Numeric 10
11% Numeric 7
10% Ace
9% Numeric 6
9% Numeric 4
9% King
...
1% Jack
collect r
r
instance Arbitrary Hand where arbitrary = rHand size Empty = 0 size (Add c h) = 1+size h prop_Hand h = collect (size h) True
quickCheck prop_Hand
+++ OK, passed 100 tests:
47% 0
20% 1
13% 2
11% 3
4% 4
2% 5
1% 7
1% 6
1% 12
rHand :: Gen Hand rHand = frequency [(1,return Empty), (4,do c <- rCard h <- rHand return (Add c h))]
quickCheck prop_Hand
+++ OK, passed 100 tests:
19% 1
19% 0
13% 2
10% 4
8% 6
6% 3
5% 9
5% 5
3% 7
...
insert
insert 'c' "abdef"
"abcdef"
prop_insert_1 :: Integer -> [Integer] -> Bool prop_insert_1 x xs = isOrdered (insert x xs)
quickCheck prop_insert_1
*** Failed! Falsifiable (after 3 tests and 4 shrinks):
0
[0,-1]
prop_insert_2 :: Integer -> [Integer] -> Property prop_insert_2 x xs = isOrdered xs ==> isOrdered (insert x xs)
quickCheck prop_insert_2
*** Gave up! Passed only 68 tests.
orderedList :: (Arbitrary a, Ord a) => Gen [a]
prop_insert_3 x = forAll orderedList (\xs->isOrdered (insert x xs))
prop_insert_4 x (Ordered xs) = isOrdered (insert x xs)
prop_insert_4 x (Ordered xs) = isOrdered (insert x xs)
data OrderedList a = Ordered [a] instance (Ord a,Arbitrary a) => Arbitrary (OrderedList a) where arbitrary = Ordered <$> orderedList
orderedList
Card
IO
Gen
do
IO
Gen