haskell - 有没有办法在 Haskell QuickCheck 中生成用于测试的值?
问题描述
我有 2 种数据类型用于表示一元系统中的自然数
data Valoare_Unar = Unu deriving(Show);
data Numar_Unar = Invalid | Unar [Valoare_Unar] deriving(Show);
我有这些函数可以将此数字从整数转换为我的数据类型,反之亦然。
convert :: Unar.Numar_Unar -> Integer
convert Unar.Invalid = (-1)
convert (Unar.Unar xs)
| null xs = 0
| otherwise = 1 + convert (Unar.Unar (tail xs))
convert' :: Integer -> Unar.Numar_Unar
convert' (-1) = Unar.Invalid
convert' x = fromInteger x :: Unar.Numar_Unar
我想测试一下(convert' (convert _)) == _
,我有
prop_check xs = Utils.convert' (Utils.convert xs) == xs where types = xs::Unar.Numar_Unar
。
我已经创建了任意数据类型的实例,但是我在弄清楚我应该如何为“Unar”构造函数生成值时遇到了问题。
instance Arbitrary Valoare_Unar where
arbitrary = elements [Unu]
instance Arbitrary Numar_Unar where
arbitrary = elements [Invalid, Unar []]
使用QC.verboseCheck prop_check
我注意到唯一的测试值是“无效”和“Unar []”。
我的问题是:如何生成像 "Unar[Unu] ; Unar[Unu,Unu,Unu] ; ... ; Unar [Unu,..,Unu]" 这样的值进行测试?
编辑:实例 Num Numar_Unar
instance Num Numar_Unar where
(+) (Unar xs) (Unar ys)
| null ys = (Unar xs)
| otherwise = (+) (Unar (xs ++ [head ys])) (Unar (tail ys))
(+) _ _ = Invalid
(-) (Unar xs) (Unar ys)
| length xs < length ys = Invalid
| null ys = Unar xs
| xs == ys = Unar []
| otherwise = (-) (Unar (tail xs)) (Unar (tail ys))
(-) _ _ = Invalid
(*) (Unar xs) (Unar ys)
| null ys = Unar []
| otherwise = (+) (Unar xs) ((*) (Unar xs) (Unar (tail ys)))
(*) _ _ = Invalid
abs (Unar xs) = Unar xs
abs Invalid = Invalid
signum (Unar xs)
| null xs = Unar []
| otherwise = Unar [Unu]
signum Invalid = Invalid
fromInteger x
| x < 0 = Invalid
| x == 0 = Unar []
| otherwise = (+) (Unar [Unu]) (fromInteger (x-1))
解决方案
arbitrary = elements [Invalid, Unar []]
意思是“当我arbitrary
在这种类型上运行时,总是给我Invalid
或Unar []
”。一个合适的Arbitrary
实例如下所示:
instance Arbitrary Numar_Unar where
arbitrary = frequency [(1, return Invalid), (3, Unar <$> arbitrary)]
这将使arbitrary
生成Invalid
1/4 的时间和Unar
3/4 的时间。当它生成时Unar
,它会调用类型arbitrary
来[Valoare_Unar]
获取一个包含随机数量元素的列表,而不是总是没有。您还应该考虑向shrink
该类添加一个方法,如下所示:
shrink Invalid = []
shrink (Unar []) = [Invalid]
shrink (Unar (Unu:xs)) = [Invalid, Unar [], Unar xs]
推荐阅读
- java - 如何将文本值获取到数组?
- powershell - 将值附加到变量
- angular - 使用带有授权标头的httpclient请求url时Angular 6 HTTP 409冲突
- javascript - 响应数据未定义
- javascript - 我想使用 javascript 显示 AM / PM
- java - Firebase 出现内部错误。[7:]
- domain-driven-design - 集合不变量的总和阻止聚合根创建/更新
- vba - 为什么第一轮后vba循环失败?
- flutter - 寻找一个很好的示例工作代码,用于从 Flutter 中的 URL 下载任何文件。如果它带有本机下载器,那么这将非常好
- python - sqlite python,嵌套循环停止主循环