Pregunta

Tengo un Atomic clase de tipo, que define funciones para convertir determinados tipos de / a un valor de envoltura (Atom). Me gustaría definir una propiedad QuickCheck que establece: "para todas las instancias de Atomic, cualquier valor puede ser almacenada y recuperada en forma segura". La propiedad es el siguiente:

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 correr a través de este inmueble 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 de 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? Si no, se pueden hacer forallAtoms al trabajo o es que no soportados por el sistema de tipos?

¿Fue útil?

Solución

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

try

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

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

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top