Testing 针对多种类型测试QuickCheck属性?

Testing 针对多种类型测试QuickCheck属性?,testing,haskell,quickcheck,Testing,Haskell,Quickcheck,我有一个类型类Atomic,它定义了将某些类型转换为包装器值(Atom)或从包装器值转换为特定类型的函数。我想定义一个QuickCheck属性,该属性声明:“对于原子的所有实例,可以安全地存储和检索任何值”。该属性如下所示: class Atomic a where toAtom :: a -> Atom fromAtom :: Atom -> Maybe a prop_AtomIdentity x = fromAtom (toAtom x) == Just x

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

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属性?如果没有,FORALATOMS是否可以工作,或者类型系统是否不支持它?

我无法编译您的代码,因此。。。盲射:

试一试

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


在我看来,您的问题是GHC试图在整个函数范围内为
x:(a->Bool)
中的
a
插入一种类型,但您已经给出了三种不同的类型。

真不敢相信它这么简单。谢谢
forallAtoms :: (forall a. (Atomic a, Show a) => a -> Bool) -> [TestOptions -> IO TestResult]