有没有办法显示为 quickCheck 和 quickBatch 生成的值
Is there a way to show values which are generated for quickCheck and quickBatch
我 运行 quickBatch 测试此代码:
data List a =
Nil
| Cons a (List a)
deriving (Eq, Show)
instance Functor List where
fmap _ Nil = Nil
fmap f (Cons a as) = Cons (f a) (fmap f as)
instance Applicative List where
pure a = Cons a Nil
Nil <*> _ = Nil
_ <*> Nil = Nil
(Cons f fs) <*> as = fmap f as `append` (fs <*> as)
append :: List a -> List a -> List a
append Nil ys = ys
append (Cons x xs) ys = Cons x $ xs `append` ys
instance Arbitrary a => Arbitrary (List a) where
arbitrary = frequency [(1, return Nil), (2, Cons <$> arbitrary <*> arbitrary)]
main :: IO ()
main =
hspec $ do
describe "List" $ do
it "Functor" $
property (quickBatch $ functor (undefined :: List (Int, Float, String)))
it "Applicative" $
property (quickBatch $ applicative (undefined :: List (Int, Float, String)))
当 Arbitrary 的权重为 1 和 2 时,所有测试总共需要 5 秒才能完成。但是,当我将权重设置为 1 和 499(Nil 取一次,实际值取 499 次,是否正确?)时,所有测试都比较慢,尤其是每个应用组合测试需要大约 5 分钟。所以我想知道这种行为从何而来,也许我能以某种方式看到生成的值。
我们可以计算具有 n 个元素的列表的概率分布。如果你实施它:
instance Arbitrary a => Arbitrary (List a) where
arbitrary = frequency [(1, return Nil), (<i>k</i>, Cons <$> arbitrary <*> <b>arbitrary</b>)]
则有1/(1+k)表示列表终止。请注意,粗体字的 arbitrary
是您在此处定义的任意值,因此您进行了 递归 调用。因此,这意味着长度为 n 的列表的可能性为:
P(|L|=n) = kn-1/(1+k)n
这是一个Gemetrical distribution [wiki],列表的平均长度将是k(几何分布变量的平均值是 k+1,但 包含 Nil
元素)。所以这意味着如果你将 k 设置为 499
,你将平均生成一个包含 499 个元素的列表,而如果你将 k
设置为 2
, 它生成平均长度为 2 的列表。当然,计算量会随着列表的长度而增加。
我 运行 quickBatch 测试此代码:
data List a =
Nil
| Cons a (List a)
deriving (Eq, Show)
instance Functor List where
fmap _ Nil = Nil
fmap f (Cons a as) = Cons (f a) (fmap f as)
instance Applicative List where
pure a = Cons a Nil
Nil <*> _ = Nil
_ <*> Nil = Nil
(Cons f fs) <*> as = fmap f as `append` (fs <*> as)
append :: List a -> List a -> List a
append Nil ys = ys
append (Cons x xs) ys = Cons x $ xs `append` ys
instance Arbitrary a => Arbitrary (List a) where
arbitrary = frequency [(1, return Nil), (2, Cons <$> arbitrary <*> arbitrary)]
main :: IO ()
main =
hspec $ do
describe "List" $ do
it "Functor" $
property (quickBatch $ functor (undefined :: List (Int, Float, String)))
it "Applicative" $
property (quickBatch $ applicative (undefined :: List (Int, Float, String)))
当 Arbitrary 的权重为 1 和 2 时,所有测试总共需要 5 秒才能完成。但是,当我将权重设置为 1 和 499(Nil 取一次,实际值取 499 次,是否正确?)时,所有测试都比较慢,尤其是每个应用组合测试需要大约 5 分钟。所以我想知道这种行为从何而来,也许我能以某种方式看到生成的值。
我们可以计算具有 n 个元素的列表的概率分布。如果你实施它:
instance Arbitrary a => Arbitrary (List a) where
arbitrary = frequency [(1, return Nil), (<i>k</i>, Cons <$> arbitrary <*> <b>arbitrary</b>)]
则有1/(1+k)表示列表终止。请注意,粗体字的 arbitrary
是您在此处定义的任意值,因此您进行了 递归 调用。因此,这意味着长度为 n 的列表的可能性为:
P(|L|=n) = kn-1/(1+k)n
这是一个Gemetrical distribution [wiki],列表的平均长度将是k(几何分布变量的平均值是 k+1,但 包含 Nil
元素)。所以这意味着如果你将 k 设置为 499
,你将平均生成一个包含 499 个元素的列表,而如果你将 k
设置为 2
, 它生成平均长度为 2 的列表。当然,计算量会随着列表的长度而增加。