2011-08-22 3 views
3

J'écris un test pour une fonction de recherche binaire que j'ai écrite.Comment utiliser quickcheck dans

module Tests where 

import Data.List (sort) 
import Test.QuickCheck 
import BinarySearch (binarySearch) 

prop_equals_elem x xs = (binarySearch x $ sort xs) == (x `elem` xs) 

args = Args {replay = Nothing, maxSuccess = 200, maxDiscard=200, maxSize=200, chatty = False} 

main = do 
    quickCheck (prop_equals_elem :: (Ord a) => a -> [a] -> Bool) 

Il fonctionne bien à l'aide quickcheck en ghci mais quand je tente d'exécuter principal, il donne l'erreur

Tests.hs:12:5: 
    Ambiguous type variable `a0' in the constraints: 
     (Arbitrary a0) arising from a use of `quickCheckWith' 
      at Tests.hs:12:5-18 
     (Show a0) arising from a use of `quickCheckWith' 
      at Tests.hs:12:5-18 
     (Ord a0) arising from an expression type signature 
      at Tests.hs:12:26-72 

Pourquoi ça marche pas mais fait dans ghci?

+0

Pensez également à utiliser http://hackage.haskell.org/package/test-framework – alternative

Répondre

4

Cela est probablement causé par le extended defaulting rules in GHCi. Lorsque vous testez une fonction comme celle-ci, vous devez utiliser un type d'élément concret. GHCi utilisera par défaut le type d'élément () en raison des règles étendues, mais cela ne se produira pas lors de la compilation du code normalement, donc GHC vous dit qu'il ne peut pas déterminer quel type d'élément utiliser.

Vous pouvez par exemple utiliser Int place pour le test. () est assez inutile pour tester cette fonction, car tous les éléments seraient les mêmes.

quickCheck (prop_equals_elem :: Int -> [Int] -> Bool) 

Si cela fonctionne pour Int, il devrait fonctionner pour tout type en raison de paramétricité. Lorsque vous exécutez un test QuickCheck, QuickCheck doit savoir comment générer des données.

3

Ici, vous avez seulement indiqué que votre code devrait fonctionner avec un type arbitraire de la classe de type Ord, ce qui ne suffit pas pour commencer le test. D'où l'erreur sur les classes de types ambiguës.

Si vous avez juste besoin d'une instance Ord arbitraire, telle qu'elle apparaît ici, alors quelque chose comme Int serait un bon choix pour vos tests. C'est un type simple avec un ordre linéaire. Donc, essayez de fixer votre genre à Int dans main, comme dans:

quickCheck (prop_equals_elem :: Int -> [Int] -> Bool) 

Quant à savoir pourquoi cela fonctionne dans GHCi, la réponse est en défaut. GHCi paramètre par défaut les variables à () chaque fois que possible, juste pour éviter de donner de fausses erreurs dans des situations où vous ne vous souciez pas vraiment d'une valeur. En fait c'est un choix affreux: vous ne testerez rien d'intéressant en testant uniquement avec le type ()! Donc encore une fois, la signature de type explicite est meilleure.

+1

QuickCheck peut sélectionner des éléments arbitraires d'un type donné, mais ne peut pas sélectionner des types arbitraires qui instancient un type de classe. Ce serait une amélioration intéressante, cependant. –

Questions connexes