2009-09-19 15 views
12

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?

Odpowiedz

12

nie mogę skompilować kod, więc ... ślepy strzał:

spróbować

forallAtoms :: (forall a. (Atomic a, Show a) => a -> Bool) -> [TestOptions -> IO TestResult] 

jako podpis typu. To wymaga rozszerzenia języka -XRankNTypes.

Problem masz, jak ja to widzę, że GHC próbuje znaleźć jeden typ wstawić do a w x :: (a -> Bool) dla całego zakresu funkcji, ale już tam dać trzy różne.

+0

Nie mogę uwierzyć, że to było takie proste. Dzięki! –

Powiązane problemy