2014-11-27 13 views
6

Haskell’de yeniyim. Şimdiye kadar çok güzel, ancak QuickCheck özelliklerim için kopya yapıştırmayla karşılaşıyorum ve bunu düzeltmek istiyorum.QuickCheck parametrelerini nasıl sınırlandırabilirim, ör. sadece negatif olmayan mürekkepleri kullanın?

İşte uydurma bir örnek:

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

QuickCheck negatif sayılar üreten çünkü bu işe yaramaz, bu yüzden bu çözüm için google denedim

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

olsun, ve ben buldum örneğin NonNegative ve ==>, ama nasıl çalıştıklarını anlamıyorum.

Yukarıdaki örneği, i ve j'nin asla negatif olmaması için nasıl kısıtlarım? Ve ayrıca, ne de çok yüksek değil mi? Yani: (örtük yeniden ihraç değilse, Test.QuickCheck.Modifiers itibaren) 0 <= i,j < length ints

+0

"0 <= i, j ErikR

+0

@ user5402" demek istediğimi düşünüyorum. Evet, teşekkürler! Bunu değiştireceğim. Cevabınızı mümkün olan en kısa sürede kontrol edeceğim, çok iyi görünüyor. –

cevap

5

bu şekilde kullanılabilecek sarmalayıcılarını Kısıtlayıcı:

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

Sen modifiye dağılımına sahip a olarak SomeWrapper a davranabilirsiniz. Örneğin, NonNegative a, a >= 0'un olmasını sağlar. Sarmalayıcı oluşturulduktan sonra, değer desen eşleştirmeli veya açık erişim sağlayıcı ile elde edilebilir (bu durumda getNonNegative).

Endekslerinizin en yüksek kenar boşluğunu kısıtlamak için, sanırım sarmalayıcılarla (Haskkell tipi sistemde, değeri olan bir türü, bu durumda liste uzunluğunu parametrelemek imkansız) mümkün değil. Ancak, ==> operatör ile size test için keyfi bir boole kısıtlamayı ekleyebilirsiniz:

Diğer şekilde çalışır
prop_Myfunc ints (NonNegative i, NonNegative j) = i < l && j < l ==> ints !! i == ints !! j where 
    l = length ints 

: koşul doğru olmadığında, sadece şimdiki test vakası atar. Ancak dikkatli olun: çok fazla atılmış vaka varsa (durum çok kısıtlayıcı), test çok daha az yararlı olur. Kayıpsız bir davranış genellikle shrink test verileriyle elde edilebilir, ancak diğer bir konu.

+0

Teşekkür ederiz! Bu tam olarak ihtiyacım olan şey. –

10

İlk önce, özel bir Gen ... işlevinin nasıl yazılacağı ve forAll birleştiricinin nasıl kullanılacağı hakkında bir örnek için bkz. this SO answer. Burada

Ve boş olmayan bir liste için bir jeneratör yazıp listeye iki geçerli negatif olmayan endeksleri için yapılması gerekenler:

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) 
+0

Çok teşekkür ederim. Bundan çok şey öğrendim. Yuuri'nin cevabı istediğim şeye daha yakındı, ama keşke kabul edebilseydim. En azından bir oy var. –

+1

Aslında, bu çözümü kendiminkinden daha çok seviyorum :) – Yuuri

0

sen ve ben nihayet buldum gibi benzer bir durumda olduğunu nasıl ==> kullanın: "Koşullu Özellikler" bölümünde, http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html.

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

(bu özel örnekte üzerinde test etmedim, şu şekildedir: sizin örnek ile

, sen Property ile Bool değiştirip mülkiyet testten önce değişkenlerle ilgili gereksinimleri eklemek zorunda kalacak ama benzer bir durumda benim için çalıştı.) ==>: (==>) :: Testable prop => Bool -> prop -> Property: .

İlgili konular