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 vonAtomickann 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?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage