Testowanie właściwości QuickCheck pod kątem wielu typów?

Mam klasę typuAtomic, który definiuje funkcje do konwersji niektórych typów na / z wartości opakowania (Atom). Chciałbym zdefiniować właściwość QuickCheck, która stwierdza: „dla wszystkich wystąpieńAtomic, każda wartość może być przechowywana i pobierana bezpiecznie. ”Właściwość wygląda tak:

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

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

Jeśli jednak spróbuję uruchomić tę właściwość za pomocą QuickCheck, to po prostu wybiera jedną instancję (Bool) i testuje to. Obecnie pracuję nad tym, definiując podpisy typów dla każdego obsługiwanego typu atomowego na liście testowej, ale jest to pełne i podatne na błędy:

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

Próbuję zdefiniować funkcję, która zrobi to automatycznie:

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

Ale kończy się błędem sprawdzania typu:

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)]

Czy istnieje lepszy sposób na przetestowanie właściwości QC względem wielu typów? Jeśli nie, czy forallAtoms może zostać uruchomiony lub czy nie jest obsługiwany przez system typów?

questionAnswers(1)

yourAnswerToTheQuestion