Mam klasy typu Atomic
, która definiuje funkcje do konwersji niektórych typów do/z wartości opakowania (Atom
). Chciałbym zdefiniować właściwość QuickCheck, która stwierdza: "dla wszystkich instancji Atomic
każda wartość może być bezpiecznie przechowywana i pobierana". Obiekt wygląda następująco:Testowanie właściwości QuickCheck w stosunku do wielu typów?
class Atomic a where
toAtom :: a -> Atom
fromAtom :: Atom -> Maybe a
prop_AtomIdentity x = fromAtom (toAtom x) == Just x
Jednakże, jeśli po prostu spróbować uruchomić tę właściwość przez QuickCheck, to po prostu wybiera jedną instancję (Bool
) i testach. Obecnie pracuję dookoła, że poprzez zdefiniowanie typu podpisy dla każdego obsługiwanego typu atomowej na liście testowej, ale to jest gadatliwy 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 to nie z błędem typecheck:
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 sprawdzenie właściwości QC przed wieloma typami? Jeśli nie, to czy można działać poprawnie, czy nie jest to wspierane przez system typów?
Nie mogę uwierzyć, że to było takie proste. Dzięki! –