Following the amazing Haskell Programming book, I was stuck for a while on the Monad chapter.
An exercise asks to write a
List data type, implement its
Monad instances and then test them with QuickCheck and Checkers.
Having this data type:
data List a = Nil | Cons a (List a) deriving (Eq, Show)
I had write its
Arbitrary instance to generate values for the tests.
There’s a useful function in QuickCheck called sized that can be used for this.
The type signature is:
sized :: (Int -> Gen a) -> Gen a
What’s needed to use it is a function that takes a
Int and returns a
This is the function I ended up with:
arbitraryList :: Arbitrary a => Int -> Gen (List a) arbitraryList m | m == 0 = return Nil | m > 6 = arbitraryList 6 | otherwise = Cons <$> arbitrary <*> (arbitraryList (m-1))
I capped the length at 6 to avoid super long lists.
Arbitrary instance is then:
instance Arbitrary a => Arbitrary (List a) where arbitrary = sized arbitraryList