有什么方法可以在 Haskell QuickCheck 中以这种方式生成测试值吗?
Is there any way to generate values for testing this way in 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
为此。
我已经将我的数据类型实例化为 Arbitrary,但我在弄清楚如何为“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]”这样的值用于测试?
编辑:实例编号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
时,它会为 [Valoare_Unar]
类型调用 arbitrary
以获取包含随机元素数的列表,而不是总是 none。您还应该考虑向 class 添加一个 shrink
方法,如下所示:
shrink Invalid = []
shrink (Unar []) = [Invalid]
shrink (Unar (Unu:xs)) = [Invalid, Unar [], Unar xs]
我有 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
为此。
我已经将我的数据类型实例化为 Arbitrary,但我在弄清楚如何为“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]”这样的值用于测试?
编辑:实例编号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
时,它会为 [Valoare_Unar]
类型调用 arbitrary
以获取包含随机元素数的列表,而不是总是 none。您还应该考虑向 class 添加一个 shrink
方法,如下所示:
shrink Invalid = []
shrink (Unar []) = [Invalid]
shrink (Unar (Unu:xs)) = [Invalid, Unar [], Unar xs]