Testen von QuickCheck-Eigenschaften für mehrere Typen?
Ich habe eine TypenklasseAtomic
, das Funktionen zum Konvertieren bestimmter Typen in / von einem Wrapper-Wert definiert (Atom
). Ich möchte eine QuickCheck - Eigenschaft definieren, die lautet: "für alle Instanzen vonAtomic
kann jeder Wert sicher gespeichert und abgerufen werden ". Die Eigenschaft sieht folgendermaßen aus:
class Atomic a where
toAtom :: a -> Atom
fromAtom :: Atom -> Maybe a
prop_AtomIdentity x = fromAtom (toAtom x) == Just x
Wenn ich jedoch nur versuche, diese Eigenschaft über QuickCheck auszuführen, wird nur eine Instanz ausgewählt (Bool
) und testet es. Ich arbeite derzeit daran, indem ich Typensignaturen für jeden unterstützten atomaren Typ in der Testliste definiere. Dies ist jedoch ausführlich und fehleranfällig:
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 erledigt:
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 schlägt fehl mit einem Tippfehler:
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 eine bessere Möglichkeit, eine QC-Eigenschaft gegen mehrere Typen zu testen? Wenn nicht, kann forallAtoms zum Laufen gebracht werden oder wird dies vom Typsystem nicht unterstützt?