Hspec和QuickCheck-模糊类型变量a0?

时间:2018-10-14 13:26:45

标签: haskell quickcheck hspec

我在Haskell中编写了一个函数,该函数接收一个任意元素的列表并返回(映射)一个元组列表。每个元组都包含原始元素和一个分数,列表中的所有分数均加1(因此,我只需使用1 ``div`` length xs计算一次分数并将其应用于所有元素)。这是代码:

uniform :: [a] -> [(a, Int)]
uniform xs = map (\x -> (x, prob)) xs
  where prob = 1 `div` (length xs)

(免责声明:这实际上是一个稍微简化的版本,但是我产生的行为完全相同,因此希望足够)。

我正在尝试通过使用Hspec和Quickcheck进行基于属性的测试来覆盖这一点:

spec = do
    describe "uniform" $ do

        it "produces a uniform distribution summing to 1" $ property $
            let totalProbability ((_, p):xs) = p + (totalProbability xs)
            in (\xs -> (totalProbability $ uniform xs) `shouldBe` 1)

但是,当我运行它时,出现此错误:

• Ambiguous type variable ‘a0’ arising from a use of ‘property’
  prevents the constraint ‘(Arbitrary a0)’ from being solved.
  Probable fix: use a type annotation to specify what ‘a0’ should be.
  These potential instances exist:
    instance (Arbitrary a, Arbitrary b) => Arbitrary (Either a b)
      -- Defined in ‘Test.QuickCheck.Arbitrary’
    instance Arbitrary Ordering
      -- Defined in ‘Test.QuickCheck.Arbitrary’
    instance Arbitrary Integer
      -- Defined in ‘Test.QuickCheck.Arbitrary’
    ...plus 19 others
    ...plus 62 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In the second argument of ‘($)’, namely
    ‘property
       $ let totalProbability ((_, p) : xs) = p + (totalProbability xs)
         in (\ xs -> (totalProbability $ uniform xs) `shouldBe` 1)’
  In a stmt of a 'do' block:
    it "produces a uniform distribution summing to 1"
      $ property
          $ let totalProbability ((_, p) : xs) = p + (totalProbability xs)
            in (\ xs -> (totalProbability $ uniform xs) `shouldBe` 1)
  In the second argument of ‘($)’, namely
    ‘do it "produces a uniform distribution summing to 1"
          $ property
              $ let totalProbability ((_, p) : xs) = ...
                in (\ xs -> (totalProbability $ uniform xs) `shouldBe` 1)’

| 12 |它“产生一个总和为1的均匀分布”    | ^^^^^^^^^^^ ...

我想我在某个地方没有给QuickCheck有关如何生成测试值的足够信息,但是我不确定从这里去哪里。

任何帮助将不胜感激。

谢谢!

1 个答案:

答案 0 :(得分:1)

您需要为xs指定类型:这是字符串列表吗?整数?布尔值?这样,QuickCheck可以生成该类型的随机样本。

您可以编写,例如:

...
in (\xs -> (totalProbability $ uniform (xs :: [Int])) `shouldBe` 1)