【问题标题】:Testing QuickCheck properties against multiple types?针对多种类型测试 QuickCheck 属性?
【发布时间】:2009-09-20 02:40:33
【问题描述】:

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

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

prop_AtomIdentity x = fromAtom (toAtom x) == Just 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

但由于类型检查错误而失败:

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

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

【问题讨论】:

    标签: testing haskell quickcheck


    【解决方案1】:

    我无法编译你的代码,所以……盲拍:

    试试

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

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

    在我看来,您遇到的问题是 GHC 尝试在整个函数范围内为 a 找到 one 类型以插入 x :: (a -> Bool),但您已经给出了三个不同的在那里。

    【讨论】:

    • 不敢相信这么简单。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多