0

I am using QuickCheck to run arbitrary test cases on my code. However, in one portion of my code I have the type synonym:

type Vector = [Double]

I also have a few functions that accept a number of Vectors as input. However, all of these functions require that the Vectors be of the same length.

Is there a way to constrain QuickCheck so that it only generates lists of length n?

4

4 に答える 4

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

型クラスが存在しないため、役に立たないエラーが発生することはありませんが、作成するのは簡単です。

于 2013-11-04T04:25:55.060 に答える
3

==>表記法で制約を設定できます。

例は次のとおりです。

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

失敗します:

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

制約付きになりました:

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
于 2013-11-04T04:28:30.550 に答える
2

もう 1 つの明白な解決策は、タプルのリストを生成して解凍することです。たとえば、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.
于 2013-11-04T04:37:00.783 に答える
1

ここに 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.
于 2013-11-04T04:24:35.130 に答える