6

我为 foldl 编写了一个实现并想检查它是否有效,我尝试了一些案例,它似乎运行良好,但我想确定一下。

我阅读了有关 quickCheck 并尝试了它,但我似乎无法使其工作,这是代码

foldl'' :: (b -> a -> b) -> b -> [a] -> b

test :: Eq b => (b -> a -> b) -> b -> [a] -> Bool
test f e ls = foldl'' f e ls == foldl f e ls

当我运行quickCheck test它时会引发以下错误:

No instance for (Show (b0 -> a0 -> b0))
  arising from a use of `quickCheck'
Possible fix:
  add an instance declaration for (Show (b0 -> a0 -> b0))
In the expression: quickCheck prueba
In an equation for `it': it = quickCheck prueba
4

3 回答 3

7

您的属性需要三个输入:一个函数、一个元素和一个列表。问题是 QuickCheck 通常不知道如何处理函数。

QuickCheck 需要工作的一件事是能够将失败的测试用例写入控制台。为此,它需要可以在类中变成String--anything 的值Show。由于函数不在 中Show,因此不能将它们用于输入。这就是您的错误消息的来源。

一般来说,使用随机生成的函数进行测试会非常棘手。我只是写一些具体的函数,让 QuickCheck 随机生成起始值和元素列表。

于 2013-04-24T21:47:06.060 回答
6

有一种方法可以避免Show使用修饰符对输入的约束Blind,这将允许您使用 QuickCheck 的机制来生成随机函数。

-- Using Int instead of a, b which would be defaulted to () in GHCi
prueba :: Blind (Int -> Int -> Int) -> Int -> [Int] -> Bool
prueba (Blind f) e ls = foldl'' f e ls == foldl f e ls

也就是说,这意味着故障输出对于调试几乎没有用,因为它只会打印(*)盲输入。(为了演示,我定义了foldl'' = foldr . flip

> quickCheck prueba 
*** Failed! Falsifiable (after 4 tests and 2 shrinks):    
(*)
0
[1,0]
于 2013-04-25T02:17:19.993 回答
2

据我了解,在 QuickCheck 中有创建随机函数的机制(请参阅Test.QuickCheck.Function),但我不能说我对这些东西的了解足以告诉你如何使用它。

话虽如此,使用您自己选择的功能测试您的属性可能更有意义,因此您可以编写类似 的quickCheck $ prueba (+)内容,这样可以正常工作。

于 2013-04-24T21:47:34.010 回答