2009-09-19 12 views
12

Ho una classe di tipo Atomic, che definisce le funzioni per la conversione di determinati tipi in/da un valore wrapper (Atom). Mi piacerebbe definire una proprietà QuickCheck che afferma: "per tutte le istanze di Atomic, qualsiasi valore può essere memorizzato e recuperato in modo sicuro". La proprietà si presenta così:Test delle proprietà di QuickCheck contro più tipi?

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

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

Tuttavia, se cerco solo di eseguire tale proprietà attraverso QuickCheck, appena prende un'istanza (Bool) e prove di esso. Attualmente sto lavorando intorno a quel tipo con la definizione delle firme per ogni tipo atomico supportato nella lista dei test, ma questo è prolisso e incline all'errore:

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

sto cercando di definire una funzione che lo farà automaticamente :

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 

Ma non riesce con un errore 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)] 

c'è un modo migliore per testare una proprietà di controllo di qualità contro più tipi? In caso contrario, può essere fatto tutto per funzionare o non è supportato dal sistema di tipi?

risposta

12

non riesco a compilare il codice, in modo da ... colpo cieco:

provare

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

come firma tipo. Questo richiede l'estensione della lingua -XRankNTypes.

Il problema che avete, come la vedo io, è che GHC cerca di trovare un tipo da inserire per a in x :: (a -> Bool) per l'intero ambito funzione, ma che già danno tre diversi lì.

+0

Non riesco a credere che fosse così semplice. Grazie! –

Problemi correlati