是否可以显示为quickCheck和quickBatch生成的值

问题描述 投票:1回答:1

我为此代码运行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)))

[任意的权重为1和2时,所有测试总共需要5秒才能完成。但是,当我将权重设置为1和499时(一次取零,而实际值取499次,对吗?),所有测试都变慢了,特别是每个适用成分测试需要5分钟。所以我想知道这种行为是从哪里来的,也许我能以某种方式看到生成的值。

haskell quickcheck
1个回答
1
投票

我们可以计算具有n个元素的列表的概率分布。如果实现它:

instance Arbitrary a => Arbitrary (List a) where
    arbitrary = frequency [(1, return Nil), (k, Cons <$> arbitrary <*> arbitrary)]

然后有1 /(1 + k)列表终止。请注意,黑体字的arbitrary是您在此处定义的任意值,因此您进行了recursive调用。因此,这意味着长度为[[n的列表的可能性为:

P(| L | = n)= k n-1 /(1 + k)n

这是Gemetrical distribution [wiki],列表的平均长度为

k

(几何分布变量的平均值为k + 1,但includes Nil元素)。因此,这意味着如果将k设置为499,则平均将生成499个元素的列表,而如果将k设置为2,则将生成平均长度为2的列表。当然,计算工作量取决于列表的长度。
© www.soinside.com 2019 - 2024. All rights reserved.