Domanda

Ho una Atomic tipo di classe, che definisce le funzioni per la conversione di taluni tipi a / da un valore involucro (Atom). Mi piacerebbe definire una proprietà QuickCheck che recita: "per tutte le istanze di Atomic, qualsiasi valore può essere memorizzato e recuperate in modo sicuro". La proprietà si presenta così:

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 farà questo 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, possono forallAtoms essere fatto per lavorare o è che non sono supportati dal sistema tipo?

È stato utile?

Soluzione

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

try

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

come firma tipo. Ciò richiede l'estensione -XRankNTypes lingua.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top