I have a set of simple demo programs which encode/decode strings, and want to generate some quickCheck tests for them, but to limit the tests to printable strings only.
The starting point is definitely a genSafeChar generator, which can have type Gen Char. For example:
genSafeChar :: Gen Char
genSafeChar = elements ['a'..'z']
Then you can build that up into a genSafeString generator, e.g. with listOf:
genSafeString :: Gen String
genSafeString = listOf genSafeChar
At this point you have a couple of reasonable choices. Either make a newtype wrapper for String:
newtype SafeString = SafeString { unwrapSafeString :: String }
deriving Show
instance Arbitrary SafeString where
arbitrary = SafeString <$> genSafeString
(in this case you might just inline the definition of genSafeString)
and you can then use it something like this:
testWibble (SafeString str) = str == str
Or, you can use forAll at each point you need a safe string:
testWibble = forAll genSafeString $ \str -> str == str
Currently QuickCheck has a PrintableString type, which also has an instance of arbitrary, which means that you can readily generate arbitrary strings with:
arbitraryPrintableString :: Gen String
arbitraryPrintableString = getPrintableString <$> arbitrary