2016-09-02 1 views
5

Nous avons deux fonctions qui comparent 2 fonctions power différentes, et retournent true si elles retournent la même valeur (sur la même entrée). Ensuite, nous avons 2 autres fonctions qui testent ces fonctions sur 2 listes pour voir s'il y a une valeur qui ne retourne pas vrai.Générer uniquement des entiers positifs avec QuickCheck

Mais au lieu d'utiliser des listes qui vont de [1..100], nous aimerions utiliser quickcheck. Donc, il est possible d'obtenir quickcheck pour ne renvoyer que des entiers positifs.

code:

comparePower1 :: Integer -> Integer -> Bool 
comparePower1 n k = power n k == power1 n k 

comparePower2 :: Integer -> Integer -> Bool 
comparePower2 n k = power n k == power2 n k 

testing1 = and [comparePower1 n k | n <- [0..100], k <- [0..100]] 
testing2 = and [comparePower2 n k | n <- [0..100], k <- [0..100]] 
+0

http://stackoverflow.com/questions/12466580/how-to-use-modifiers-with-quickcheck-positive-in-my-case va peut-être aider? –

+0

@TomaszLewowski Pas vraiment. Je n'ai pas compris ce type classe/définition '(Integral a, Show a, Read a) => ...' –

+0

pourquoi ne pas utiliser le modificateur 'suchThat' pour le générateur? –

Répondre

7

QuickCheck a un support pour Positive numbers, mais pour le bien de ce tutoriel, je vais vous montrer comment créer votre propre générateur. L'une des principales caractéristiques de QuickCheck est que vous pouvez concevoir votre propre générateur pour produire exactement ce dont vous avez besoin. Par exemple

genPos :: Gen Int 
genPos = abs `fmap` (arbitrary :: Gen Int) `suchThat` (> 0) 

Ensuite, vous pouvez créer votre propre liste genereator

genListOfPos :: Gen [Int] 
genListOfPos = listOf genPos 

Enfin, vous pouvez utiliser forAll, passer le générateur et le profit.

main :: IO() 
main = do 
    quickCheck $ forAll genPos $ \x -> x > 0 
    quickCheck $ forAll genListOfPos $ all (> 0) 
+0

Thx, ça a marché! Une question: Pourquoi je n'ai pas besoin d'appliquer la nouvelle liste à la fonction de test, ou au moins de supprimer la liste existante ('[1..100]')? Ou peut-être que ma question devrait être: quelle est exactement cette fonction avec cette liste? –

+0

'all (> 0)' se développe en '\ xs -> all (\ x -> x> 0) xs', ce qui signifie appliquer' \ x -> x> 0 ''a chaque élément de' xs', puis lancer ' all' pour vérifier si tous les éléments sont 'True' – mariop

+0

Par souci d'efficacité, il peut être préférable de générer un' Word', d'ajouter 1, de lancer vers 'Int', de prendre la valeur absolue, puis de lancer zéro. La raison pour laquelle cela * pourrait * être meilleur est que je pense que QuickCheck essaie normalement de choisir des "petites" valeurs, donc vous pourriez avoir beaucoup de zéros à jeter. Vous devriez vérifier quelques détails avant de prendre ce conseil, cependant - je peux me tromper. – dfeuer