Generating a list of lists of Int with QuickCheck
I'm working through Real World
Haskell one of the
exercises of chapter 4 is to implement an foldr
based version of
concat
. I thought this would be a great candidate for testing with
QuickCheck since there is an existing implementation to validate my
results. This however requires me to define an instance of the
Arbitrary
typeclass that can generate arbitrary [[Int]]
. So far I have
been unable to figure out how to do this. My first attempt was:
module FoldExcercises_Test
where
import Test.QuickCheck
import Test.QuickCheck.Batch
import FoldExcercises
prop_concat xs =
concat xs == fconcat xs
where types = xs ::[[Int]]
options = TestOptions { no_of_tests = 200
, length_of_tests = 1
, debug_tests = True }
allChecks = [
run (prop_concat)
]
main = do
runTests "simple" options allChecks
This results in no tests being performed. Looking at various bits and
pieces I guessed that an Arbitrary
instance declaration was needed and
added
instance Arbitrary a => Arbitrary [[a]] where
arbitrary = sized arb'
where arb' n = vector n (arbitrary :: Gen a)
This resulted in ghci complai开发者_如何学JAVAning that my instance declaration was
invalid and that adding -XFlexibleInstances might solve my problem.
Adding the {-# OPTIONS_GHC -XFlexibleInstances #-}
directive
results in a type mismatch and an overlapping instances warning.
So my question is what's needed to make this work? I'm obviously new to Haskell and am not finding any resources that help me out. Any pointers are much appreciated.
Edit
It appears I was misguided by QuickCheck's output when in a test first manner fconcat
is defined as
fconcat = undefined
Actually implementing the function correctly indeed gives the expected result. DOOP!
[[Int]]
is already an Arbitrary
instance (because Int
is an Arbitrary
instance, so is [a]
for all a
s that are themselves instances of Arbitrary
). So that is not the problem.
I ran your code myself (replacing import FoldExcercises
with fconcat = concat
) and it ran 200 tests as I would have expected, so I am mystified as to why it doesn't do it for you. But you do NOT need to add an Arbitrary
instance.
精彩评论