这是定义任意实例的另一种方法:
newtype CAndS = CAndS String
instance Arbitrary CAndS where
arbitrary = CAndS <$> listOf (elements "CS")
除了针对参考解决方案测试函数之外,您还可以测试'C's 和'S'es 的总和是否与字符串的长度相同:
prop_CountersAddUp :: CAndS -> Bool
prop_CountersAddUp (CAndS css) = length css == cs + ss
where (cs, ss) = countCAndS css
如果字符串应该接受包含'C's 和'S'es 以外的字符(但不计算它们)的输入,您或许应该创建一个生成各种字符的生成器,但概率更高'C' 和 'S':
newtype CAndS = CAndS String
instance Arbitrary CAndS where
arbitrary = CAndS <$> listOf (frequency [ (1, return 'C')
, (1, return 'S')
, (2, arbitrary) ])
或者您可能会生成一个带有正确答案注释的字符串:
newtype CAndS = CAndS (String, Int, Int)
instance Arbitrary CAndS where
arbitrary = CAndS <$> sized (\n -> do
cs <- choose (0, n)
let ss = n - cs
css <- shuffle (replicate cs 'C' ++ replicate ss 'S')
return (css, cs, ss))
所以你可以测试它:
prop_CountersEqual :: CAndS -> Bool
prop_CountersEqual (CAndS (css, cs, ss)) = cs == cs' && ss == ss'
where (cs', ss') = countCAndS css