2009-09-19 15 views
12

Tengo una clase de tipo Atomic, que define funciones para convertir ciertos tipos a/desde un valor de contenedor (Atom). Me gustaría definir una propiedad QuickCheck que indique: "para todas las instancias de Atomic, cualquier valor puede almacenarse y recuperarse de forma segura". La propiedad es el siguiente:¿Está probando propiedades QuickCheck contra varios tipos?

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

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

Sin embargo, si yo sólo trato de ejecutar esa propiedad a través de QuickCheck, sólo se recoge un caso (Bool) y pruebas de TI. Actualmente estoy trabajando en torno a que mediante la definición de las firmas de tipos para cada tipo atómica apoyado en la lista de pruebas, pero esto es prolijo y propenso a errores:

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

Estoy tratando de definir una función que va a hacer esto de forma automática :

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 

pero falla con un error 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)] 

¿hay una mejor manera de probar una propiedad QC contra múltiples tipos? De lo contrario, ¿se puede hacer que forallAtoms funcione o que el sistema de tipos no lo admite?

Respuesta

12

no puedo compilar el código, así que ... golpe ciego:

tratar

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

como una declaración de tipo. Esto necesita la extensión de lenguaje -XRankNTypes.

El problema que tiene, como yo lo veo, es que GHC trata de encontrar una tipo para insertar a en x :: (a -> Bool) para todo el ámbito de la función, pero que ya dan tres diferentes allí.

+0

No puedo creer que fuera tan simple. ¡Gracias! –

Cuestiones relacionadas