views:

117

answers:

1

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 complaining 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!

+3  A: 

[[Int]] is already an Arbitrary instance (because Int is an Arbitrary instance, so is [a] for all as 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.

Dave Hinton
i concur. this worked fine for me in ghc 6.10.4 on OSX Leopard
barkmadley