Haskell:QuickCheck属性使用暗示使测试失败

Haskell:QuickCheck属性使用暗示使测试失败,haskell,functional-programming,quickcheck,Haskell,Functional Programming,Quickcheck,我想使用quickcheck测试以下属性: prop_zip xs ys = length xs == length ys ==> unzip (zip xs ys) == (xs,ys) 尽管根据zip和unzip的定义,该属性对于相同长度的列表应该是正确的,但快速检查以以下内容结束: *** Gave up! Passed only 49 tests. 提前感谢您的任何提示或建议 在快速检查中,生成随机测试用例很难满足的先决条件通常是个坏主意。相反,您应该小心地使用生成器

我想使用quickcheck测试以下属性:

prop_zip xs ys = length xs == length ys ==> 
    unzip (zip xs ys) == (xs,ys)
尽管根据zip和unzip的定义,该属性对于相同长度的列表应该是正确的,但快速检查以以下内容结束:

*** Gave up! Passed only 49 tests.

提前感谢您的任何提示或建议

在快速检查中,生成随机测试用例很难满足的先决条件通常是个坏主意。相反,您应该小心地使用生成器来构造自动满足前提条件的测试用例

例如,在这种情况下,您可以使用
forAll
生成与第一个列表长度相同的第二个列表:

prop_zip' (xs :: [a]) =
  forAll (vectorOf (length xs) arbitrary) $ \ (ys :: [a]) ->
  unzip (zip xs ys) == (xs, ys)

(我在这里另外使用
ScopedTypeVariables
来确定第二个列表的类型。您可能需要更改此列表以满足您的特定需要。)

Quickcheck为每个测试用例生成两个随机列表。如果
xs
ys
的长度不相同,则会丢弃它们。我怀疑这两个列表的长度几乎不一样,所以几乎所有生成的测试用例都会被丢弃,直到quickcheck放弃为止。使用
asTypeOf
可以达到相同的目标。我认为
length xs==length ys ys=>
这个术语可以确保检查只应用于相同长度的列表。是的,它确实确保了这一点。但是它仍然会随机生成两个列表,并且两个随机生成的列表长度相等的概率不是很高。这就是导致QuickCheck放弃的原因。另见fjh的评论。