我有一门打字课
Atomic
,它定义了用于将某些类型转换为包装值或从包装值转换为包装值的函数(
Atom
).我想定义一个QuickCheck属性,该属性声明:“对于
原子的
,可以安全地存储和检索任何值”。该属性如下所示:
class Atomic a where
toAtom :: a -> Atom
fromAtom :: Atom -> Maybe a
prop_AtomIdentity x = fromAtom (toAtom x) == Just x
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正常工作,或者类型系统是否不支持?