1

我开始通过做 99 个 Haskell 问题来学习 Haskell。 http://www.haskell.org/haskellwiki/H-99:_Ninety-Nine_Haskell_Problems 我想使用快速检查为每个程序/函数编写测试。

我有以下代码:

导入 Test.QuickCheck
导入文本.Printf

main = mapM_ (\(s,a) -> printf "%-25s: " s >> a) 测试

-- 1
myLast lst = 最后一个 lst
prop_1a xs x = myLast (xs ++ [x]) == (x::String)

我的最后一个' = 头。逆转
prop_1b xs x = myLast' (xs ++ [x]) == (x::String)

测试 = [("1a", quickCheck prop_1a)
         ,("1b", quickCheck prop_1b)
         ]

我可能会写myLast'',myLast'''等。有没有一种方法可以测试所有这些方法而无需复制代码和快速检查属性?

相关问题:现在,我告诉 quickcheck 使用字符串。有没有办法随机使用不同的类型进行测试?

4

2 回答 2

6

只需将要测试的函数作为另一个参数:

prop_1 last xs x = last (xs ++ [x]) == (x :: Int)

tests = zipWith mkTest ['a'..] [myLast, myLast']
  where mkTest letter func = ('1':[letter], quickCheck $ prop_1 func)
于 2011-10-05T18:28:28.720 回答
2

有没有一种方法可以测试所有这些方法而无需复制代码和快速检查属性?

为什么不编写 prop 以获取函数列表,然后检查每个函数?然后你会运行它作为quickCheck (myProp [myLast, myLast', myLast'']).

编辑:我担心你可能会问 :P 要按照我上面所说的那样做,myProp应该获取一个函数列表,所有这些函数都具有与 相同的类型last,并返回一个布尔值:

myProp :: [([a] -> a)] -> Bool

但是现在我看了一下,让它也接受一个列表和一个项目可能会更好(并且更类似于你原来的方法),所以我想我会这样做:

myProp :: [([a] -> a)] -> [a] -> a -> Bool

如果列表为空,则返回 true:

myProp [] _ _ = True

如果不是,那么我们检查列表中第一个函数的属性是否成立,然后递归检查列表的其余部分:

myProp [f:fs] xs x = f (xs ++ [x]) == x && myProp fs xs x

(我不确定你为什么x::String在你的实现中写。我认为你不应该需要它——last适用于任何东西的列表,而不仅仅是字符串列表。但我还没有实际测试过,所以我假设你有一个很好的理由。)

无论如何,我认为这应该可行,但我还没有真正尝试过。请随时编辑和修复我可能犯的任何愚蠢的语法错误或其他任何错误。

于 2011-10-05T18:22:14.107 回答