2013-11-04 41 views

回答

3

一个简单的解决方案是不具有任意实例,而是像做

import Test.QuickCheck 
import Control.Monad 

prop_vec :: Int -> Gen [Double] 
prop_vec = flip replicateM arbitrary . abs 


prop_addComm :: Int -> Gen Bool 
prop_addComm i = do 
    v <- prop_vec i 
    u <- prop_vec i 
    return $ u + v = v + u --assuming you'd added a Num instance for your vectors 

从来没有一个类型类别,所以你得到的帮助较少的故障,但鞭打起来更简单。

+0

我没有资格判断哪个答案最好 - 所以我选择这个答案是因为我正在寻找一个快速解决方案。 – sdasdadas

+0

这实际上似乎需要相当长的时间才能达到QuickCheck的100个测试用例上限......我只是使用'zipWith'将这些矢量加在一起。 – sdasdadas

+0

@sdasdadas尝试约束数字的大小,我可以在 – jozefg

1

这里有一种可能性。我们将为可以构建随尺寸而定的随机值的类型定义一个新类。然后,你可以创建一个类型级别的列表或树或任何其他的并且为这些实例声明一个Arbitrary实例。

import Control.Monad 
import Test.QuickCheck 

class SizedArbitrary a where 
    sizedArbitrary :: Int -> Gen a 

instance Arbitrary a => SizedArbitrary [a] where 
    sizedArbitrary n = replicateM n arbitrary 

data Branch a b = a :+ b deriving (Eq, Ord, Show, Read) 
instance (SizedArbitrary a, SizedArbitrary b) => SizedArbitrary (Branch a b) where 
    sizedArbitrary n = liftM2 (:+) (sizedArbitrary n) (sizedArbitrary n) 

instance (SizedArbitrary a, SizedArbitrary b) => Arbitrary (Branch a b) where 
    arbitrary = arbitrarySizedIntegral >>= sizedArbitrary . abs 

然后我们就可以在ghci中加载它,并检查了它的工作原理:

*Main> let allSameLength (xs:xss) = all (==length xs) (map length xss) 
*Main> quickCheck (\(xs :+ ys) -> allSameLength [xs, ys]) 
+++ OK, passed 100 tests. 
*Main> quickCheck (\(ws :+ xs :+ ys :+ zs) -> allSameLength [ws, xs, ys, zs]) 
+++ OK, passed 100 tests. 
2

您可以使用==>表示法设置约束条件。

一个例子是:现在

*** Failed! Exception: 'Prelude.minimum: empty list' (after 1 test): 
[] 

与约束:

prop_test xs = minimum xs == (head $ sort xs) 

从而未能

prop_test xs = not (null xs) ==> minimum xs == (head $ sort xs) 

它的工作原理:

*Main> quickCheck prop_test 
+++ OK, passed 100 tests. 

你的情况:

prop_test xs ys = length xs == length ys ==> undefined -- whatever you want 
+0

中显示一个例子。这可能真的很慢,但是随机生成两个相同大小的列表的机会很渺茫。 – jozefg

2

另一个明显的解决方案是产生一个元组列表,并对其进行解压缩。例如,在ghci中:

> let allSameLength (xs:xss) = all (==length xs) (map length xss) 
> quickCheck (\xys -> let (xs, ys) = unzip xys in allSameLength [xs, ys]) 
+++ OK, passed 100 tests. 
> :{ 
| quickCheck (\wxyzs -> let 
| (wxs, yzs) = unzip wxyzs 
| (ws, xs) = unzip wxs 
| (ys, zs) = unzip yzs 
| in allSameLength [ws, xs, ys, zs]) 
| :} 
+++ OK, passed 100 tests.