2009-09-19 12 views
12

Ich habe eine Typklasse Atomic, die Funktionen zum Konvertieren bestimmter Typen zu/von einem Wrapper-Wert (Atom) definiert. Ich möchte eine QuickCheck-Eigenschaft definieren, die besagt: "Für alle Instanzen von Atomic kann jeder Wert sicher gespeichert und abgerufen werden". Die Eigenschaft sieht wie folgt aus:Testen von QuickCheck-Eigenschaften gegen mehrere Typen?

class Atomic a where 
    toAtom :: a -> Atom 
    fromAtom :: Atom -> Maybe a 

prop_AtomIdentity x = fromAtom (toAtom x) == Just x 

Allerdings, wenn ich versuche gerade diese Eigenschaft durch Quick Check zu laufen, es nimmt nur eine Instanz (Bool) und Tests es. Ich arbeite zur Zeit um die von in der Testliste für jeden unterstützten Atomtyp Typen Signaturen definiert, aber dies ist ausführlich und fehleranfällige:

containerTests = 
    [ run (prop_AtomIdentity :: Bool -> Bool) 
    , run (prop_AtomIdentity :: Word8 -> Bool) 
    , run (prop_AtomIdentity :: String -> Bool) 
    {- etc -} ] 

Ich versuche, eine Funktion zu definieren, die dies automatisch tun :

forallAtoms :: (Atomic a, Show a) => (a -> Bool) -> [TestOptions -> IO TestResult] 
forallAtoms x = 
    [ run (x :: Bool -> Bool) 
    , run (x :: Word8 -> Bool) 
    , run (x :: String -> Bool) 
    {- etc -} ] 

containerTests = forallAtoms prop_AtomIdentity 

aber es funktioniert nicht mit einem typecheck Fehler:

Tests/Containers.hs:33:0: 
    Couldn't match expected type `Word8' against inferred type `String' 
    In the first argument of `run', namely `(x :: Word8 -> Bool)' 
    In the expression: run (x :: Word8 -> Bool) 
    In the expression: 
     [run (x :: Bool -> Bool), run (x :: Word8 -> Bool), 
     run (x :: String -> Bool)] 

gibt es einen besseren Weg, um eine QC Eigenschaft gegen mehrere Typen zu testen? Wenn nicht, kann forallAtoms funktionieren oder wird das vom Typsystem nicht unterstützt?

Antwort

12

kann ich nicht, Ihren Code kompilieren, so ... Blindschuss:

versuchen

forallAtoms :: (forall a. (Atomic a, Show a) => a -> Bool) -> [TestOptions -> IO TestResult] 

als eine Art Signatur. Dies benötigt die Spracherweiterung -XRankNTypes.

Das Problem, das Sie haben, wie ich es sehe, ist, dass GHC ein Typ für a in x :: (a -> Bool) für den gesamten Funktionsumfang einfügen finden versucht, aber man bereits drei verschiedene geben.

+0

Ich kann nicht glauben, dass es so einfach war. Vielen Dank! –

Verwandte Themen