针对多种类型测试QuickCheck属性? [英] Testing QuickCheck properties against multiple types?

查看:137
本文介绍了针对多种类型测试QuickCheck属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类型类 Atomic ,它定义了将某些类型转换为/从一个包装值( Atom )。我想定义一个QuickCheck属性,其中指出:对于 Atomic 的所有实例,可以安全地存储和检索任何值。该属性如下所示:

  class Atomic a where 
toAtom :: a - > Atom
fromAtom :: Atom - >可能是

prop_AtomIdentity x = fromAtom(toAtom x)==只需x

然而,如果我只是试图通过QuickCheck运行该属性,它只会选择一个实例( Bool )并对其进行测试。我目前正在通过为测试列表中每种受支持的原子类型定义类型签名来解决这个问题,但这是冗长而且容易出错的:

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

我试图定义函数会自动执行此操作:

  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

但它会因为类型错误而失败:

 测试/ Containers.hs:33:0 :
在'run'的第一个参数,即'(x :: Word8 - > Bool)'
中,无法匹配预期的类型'Word8'在表达式中:run(x :: Word8 - > Bool)
在表达式中:
[run(x :: Bool - > Bool),run(x :: Word8 - > Bool ),
run(x :: String - > Bool)]

更好的方法来测试QC属性对多种类型?如果没有,可以使工作原理工作还是不被类型系统支持?

解决方案

我无法编译您的代码,所以...盲目拍摄:

尝试

  forallAtoms :: (aa(原子a,显示a)=> a  - > Bool) - > [TestOptions  - > IO TestResult] 

作为类型签名。这需要-XRankNTypes语言扩展。



正如我所看到的那样,您遇到的问题是GHC试图找到要插入的类型类型对于整个函数作用域, a 位于 x ::(a - > Bool)中,但您已经给出了三个不同的地方。


I have a type class Atomic, which defines functions for converting certain types to/from a wrapper value (Atom). I'd like to define a QuickCheck property which states: "for all instances of Atomic, any value may be stored and retrieved safely". The property looks like this:

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

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

However, if I just try to run that property through QuickCheck, it just picks one instance (Bool) and tests it. I'm currently working around that by defining type signatures for each supported atomic type in the test list, but this is verbose and error-prone:

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

I'm trying to define a function which will do this automatically:

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

But it fails with a typecheck error:

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)]

Is there a better way to test a QC property against multiple types? If not, can forallAtoms be made to work or is that not supported by the type system?

解决方案

I cannot compile your code, so ... blind shot:

try

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

as a type signature. This needs the -XRankNTypes language extension.

The problem you have, as I see it, is that GHC tries to find one type to insert for a in x :: (a -> Bool) for the entire function scope, but you already give three different there.

这篇关于针对多种类型测试QuickCheck属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆