我有一个功能,rev
,它返回属于三个类型类的类型的一些值:
rev :: (Integral a, Show a, Read a) => a -> a
rev = read . reverse . show
我想用快速检查来测试它的一些属性。不过,我对测试 Integral 类型的负值不感兴趣,因为我正在使用Integer
由于缺乏Natural
在基础库中输入。所以我想,当生成的值为负时,我们取相反的值就可以了:
prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool
prop_id n | n >= 0 = (rev.rev) n == n
| otherwise = let n' = -n in (rev.rev) n' == n'
(测试的属性在这里并不重要 - 特别是它不适用于非常基本的值,我知道这一点,这不是这个问题的主题)
然后我遇到了Positive
修改器并认为虽然我的测试现在正在运行,但以更好的方式实现它会很好。所以我尝试:
prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool
prop_id n = (rev.rev) n == n
我必须承认,当它编译时我感到很惊讶。但运行测试时出现错误:
*** Failed! Exception: 'Prelude.read: no parse' (after 1 test):
Positive {getPositive = 1}
所以我想,“嗯,必须声明这一点Positive
事物的一个实例Read
“。所以我就这么做了,但该实例已经在 QuickCheck 库中声明了,似乎是因为 ghci 对我大喊大叫。
此时我迷失了,因为我没有找到好的文档(如果有的话)。
任何帮助我理解修饰符和快速检查库中其他好东西的指针将不胜感激。