In Haskell's QuickCheck, how to generate a string such that it contains only the characters ‘S’ and ‘C’, and the position of ‘S’ and ‘C’ is random?
For example: "SCCS", "SSSS", "CCCC", "CSSCCS", ""
My use case is this:
I have two functions countCAndS :: String -> (Int, Int)
and countCAndS' :: String -> (Int, Int)
. They have the same type signature. I'd like to write a QuickCheck property such that I can pass the same string to these two different functions and check if the outputs are the same.
Let your property take a list of booleans and convert them to cs and ss.
prop_CountersEqual :: [Bool] -> Bool
prop_CountersEqual bs = countCAndS css == countCAndS' css where
css = map (\b -> if b then 'C' else 'S') bs
If you need this frequently, you may want to define a new type with a suitable Arbitrary
instance.
newtype CAndS = CAndS String
instance Arbitrary CAndS where
arbitrary = CAndS . map (\b -> if b then 'C' else 'S') <$> arbitrary
Then you can write your properties as e.g.
prop_CountersEqual' :: CAndS -> Bool
prop_CountersEqual' (CAndS css) = countCAndS css == countCAndS' css
QuickCheck provides a flurry of combinators for that, it's super easy and very elegant:
prop_CountersEqual =
forAll csString $ \s -> countCAndS s == countCAndS' s
csString :: Gen String
csString = listOf $ elements "CS"
It's also trivial to expand your dictionary, should you need it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With