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?
Ich kann nicht glauben, dass es so einfach war. Vielen Dank! –