2013-04-24 10 views
5

Ho scritto un'implementazione per foldl e volevo controllare se funzionasse, ho provato alcuni casi e sembra che funzioni bene, ma voglio essere sicuro.Utilizzo di quickCheck

ho letto su QuickCheck e l'ho provato, ma non riesco a farlo funzionare, questo è il codice

foldl'' :: (b -> a -> b) -> b -> [a] -> b 

test :: Eq b => (b -> a -> b) -> b -> [a] -> Bool 
test f e ls = foldl'' f e ls == foldl f e ls 

quando lo eseguo quickCheck test getta il seguente errore:

No instance for (Show (b0 -> a0 -> b0)) 
    arising from a use of `quickCheck' 
Possible fix: 
    add an instance declaration for (Show (b0 -> a0 -> b0)) 
In the expression: quickCheck prueba 
In an equation for `it': it = quickCheck prueba 

risposta

7

La tua proprietà richiede tre input: una funzione, un elemento e un elenco. Il problema è che QuickCheck non sa come gestire le funzioni in generale.

Una delle cose che QuickCheck deve funzionare è la possibilità di scrivere casi di test non validi sulla console. Per questo, ha bisogno di valori che può trasformarsi in un String - tutto nella classe Show. Poiché le funzioni non sono in Show, non possono utilizzarle per gli input. Ecco da dove viene il tuo messaggio di errore.

In generale, l'utilizzo di funzioni generate a caso per il test è piuttosto complicato. Vorrei solo scrivere alcune funzioni concrete e lasciare che QuickCheck generi in modo casuale il valore iniziale e l'elenco degli elementi.

2

Da quello che ho capito, c'è un meccanismo per creare funzioni casuali in QuickCheck (vedi Test.QuickCheck.Function), ma non posso dire di aver conosciuto questa roba abbastanza bene da dirti come usarlo.

Detto questo, testare la tua proprietà probabilmente ha più senso con le funzioni che hai scelto tu stesso, quindi potresti scrivere qualcosa come quickCheck $ prueba (+), che funzionerà correttamente.

6

Esiste un modo per evitare il vincolo Show sugli input utilizzando il modificatore Blind, che consente di utilizzare i macchinari di QuickCheck per la generazione di funzioni casuali.

-- Using Int instead of a, b which would be defaulted to() in GHCi 
prueba :: Blind (Int -> Int -> Int) -> Int -> [Int] -> Bool 
prueba (Blind f) e ls = foldl'' f e ls == foldl f e ls 

Detto, ciò significa l'uscita fallimento è quasi inutile per il debugging, poiché viene stampare (*) per l'ingresso vedenti. (Per la dimostrazione, ho definito foldl'' = foldr . flip)

> quickCheck prueba 
*** Failed! Falsifiable (after 4 tests and 2 shrinks):  
(*) 
0 
[1,0] 
+0

Non soggetto: Tipo di costruttore o classe 'cieco' – chamini2

+0

@ chamini2: Hai importato' Test.QuickCheck'? – hammar

+0

sì, forse perché sono su OS X? 'Ghci --version: The Glorious Glasgow Haskell Compilation System, versione 7.4.2' – chamini2

Problemi correlati