簡體   English   中英

如何約束QuickCheck參數,例如僅使用非負的int?

[英]How can I constraint QuickCheck parameters, e.g. only use non-negative ints?

我是Haskell的新手。 到目前為止,這是非常好的,但我正在嘗試復制粘貼我的QuickCheck屬性,我想解決這個問題。

這是一個簡單的例子:

prop_Myfunc :: [Int] -> (Int,Int) -> Bool
prop_Myfunc ints (i,j) = ints !! i == ints !! j

這不起作用,因為QuickCheck生成負數,所以我得到

*** Failed! (after 2 tests and 2 shrinks):                               
Exception:
  Prelude.(!!): negative index

我試圖谷歌尋求解決方案,我發現例如NonNegative和==>,但我不明白它們是如何工作的。

我怎樣才能限制上面的例子,以便i和j永遠不會消極? 而且,既不是太高了? 即: 0 <= i,j < length ints

首先,請參閱此SO答案 ,了解如何編寫自定義Gen ...函數以及如何使用forAll組合器的forAll

以下是如何為列表中的非空列表和兩個有效的非負索引編寫生成器:

import Test.QuickCheck

genArgs :: Gen ( [Int], Int, Int )
genArgs = do
  x <- arbitrary
  xs <- arbitrary
  let n = length xs
  i <- choose (0,n)
  j <- choose (0,n)
  return ( (x:xs), i, j) -- return a non-empty list

test = quickCheck $ forAll genArgs $ \(xs,i,j) -> prop_myfunc xs (i,j)

約束包裝器(來自Test.QuickCheck.Modifiers ,如果它們不是隱式Test.QuickCheck.Modifiers )可以這樣使用:

prop_Myfunc :: [Int] -> (NonNegative Int, NonNegative Int) -> Bool
prop_Myfunc ints (NonNegative i, NonNegative j) = ints !! i == ints !! j

你可以把SomeWrapper a作為a具有修改的分布。 例如, NonNegative a確保a >= 0 生成包裝器后,可以使用模式匹配或顯式訪問器(在本例中為getNonNegative )獲取值。

至於約束索引的上邊距,我認為使用包裝器是不可能的(在Haskkell類型系統中不可能使用值參數化類型,在這種情況下是列表長度)。 但是,使用==>運算符,您可以為測試添加任意布爾約束:

prop_Myfunc ints (NonNegative i, NonNegative j) = i < l && j < l ==> ints !! i == ints !! j where
    l = length ints

它以其他方式工作:當條件不成立時,它只是丟棄當前的測試用例。 但要小心:如果拋出的案例太多(條件限制太多),那么測試就變得不那么有用了。 通過shrink測試數據通常可以實現“無損”行為,但這是另一個主題。

我遇到了與你類似的情況,我終於找到了如何使用==>這里: http//www.cse.chalmers.se/~rjmh/QuickCheck/manual.html ,在“條件屬性”部分。

在您的示例中,您必須使用Property替換Bool並在屬性測試之前插入有關變量的要求,如下所示:

prop_Myfunc :: [Int] -> (Int,Int) -> Property
prop_Myfunc ints (i,j) = (i >= 0 && j >= 0) ==> ints !! i == ints !! j

(我沒有對這個特定的例子進行過測試,但是對於類似的情況,它對我有用。)

注意類型==> :( (==>) :: Testable prop => Bool -> prop -> Property

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM