2012-09-17 10 views
7

Ich habe eine Funktion, rev, die einen Wert für einen Typ zurückgibt, die in drei typeclasses ist:So verwenden Modifikatoren mit Quickcheck (Positive in meinem Fall)

rev :: (Integral a, Show a, Read a) => a -> a 
rev = read . reverse . show 

Ich möchte einige testen Eigenschaft darüber mit Quickcheck. Allerdings bin ich nicht daran interessiert, negative Werte von Integral-Typen zu testen, weil ich Integer durch das Fehlen eines Natural Typs in der Basisbibliothek verwende. Also dachte ich, lassen Sie uns das Gegenteil von dem Wert annehmen erzeugt wird, wenn der erzeugte Wert negativ ist, und ich werde in Ordnung sein:

prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool 
prop_id n | n >= 0 = (rev.rev) n == n 
      | otherwise = let n' = -n in (rev.rev) n' == n' 

(die Eigenschaft getestet ist hier nicht wichtig - insbesondere es gilt nicht für sehr grundlegende Werte und ich bin mir dessen bewusst, es ist nicht das Thema dieser Frage)

Dann lief ich in die Positive Modifikator und dachte, dass, obwohl mein Test jetzt funktionierte, wäre es schön, es in einem zu implementieren schöner Weg. Also habe ich es versucht:

prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool 
prop_id n = (rev.rev) n == n 

Ich muss zugeben, ich war überrascht, als es kompiliert. Aber dann tauchte ein Fehler bei der Durchführung des Tests:

*** Failed! Exception: 'Prelude.read: no parse' (after 1 test): 
Positive {getPositive = 1} 

Also dachte ich, „MMK, muss erklären, dieses Positive Sache eine Instanz von Read“. Also habe ich genau das getan, aber die Instanz ist bereits in der QuickCheck-Bibliothek deklariert, es scheint, weil Ghci mich angeschrien hat.

Und an diesem Punkt bin ich verloren, denn ich finde keine gute Dokumentation (falls vorhanden).

Jeder Zeiger, der mir hilft, Modifikatoren und andere nette Dinge in der Quickcheck-Bibliothek zu verstehen, wird geschätzt.

+5

Es gibt keine Syntaxanalyse, weil 'rev (Positive {getPositive = 1})' 'read}} 1 = evitisoPteg {evitisoP" '. –

Antwort

17

Die übliche Art, diese Modifikatoren zu verwenden, besteht darin, eine Musterübereinstimmung an ihnen vorzunehmen, z.

prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool 
prop_id (Positive n) = (rev.rev) n == n 

Auf diese Weise n wird den zugrunde liegenden Typ.

+0

Blah hat nicht einmal daran gedacht, das zu versuchen. Wie dumm von mir. Vielen Dank :) – m09

Verwandte Themen