gpt4 book ai didi

haskell - 使用 Quickcheck 测试类型类,可变数量的参数

转载 作者:行者123 更新时间:2023-12-01 02:14:05 24 4
gpt4 key购买 nike

我有一个戒指类型类,它看起来像这样:

class Ring a where
addId :: a
addInverse :: a -> a
mulId :: a
add :: a -> a -> a
mul :: a -> a -> a

对于这个类,我有几个实例,例如
instance Ring Matrix where ...
instance Ring Integer where ...
instance Ring Modulo where ...

为了测试这些实例,我进行了以下快速检查测试:
prop_AddId :: (Ring a, Eq a, Arbitrary a) => a -> Bool
prop_AddInv :: (Ring a, Eq a, Arbitrary a) => a -> Bool
prop_MulId :: (Ring a, Eq a, Arbitrary a) => a -> Bool
prop_AddCommutative :: (Ring a, Eq a, Arbitrary a) => a -> a -> Bool
prop_AddAssociative :: (Ring a, Eq a, Arbitrary a) => a -> a -> a -> Bool
prop_MulAssociative :: (Ring a, Eq a, Arbitrary a) => a -> a -> a -> Bool
prop_Distributive :: (Ring a, Eq a, Arbitrary a) => a -> a -> a -> Bool

我不确定如何为我的所有类实例运行这些测试用例。我找到了解决方案 here
这导致以下情况:
forallRings :: (forall a. (Ring a, Arbitrary a, Eq a) => a -> Bool) -> [IO ()]
forallRings x =
[ quickCheck (x :: Matrix -> Bool)
, quickCheck (x :: Integer -> Bool)
, quickCheck (x :: Modulo -> Bool)
]
forallRings2 :: (forall a. (Ring a, Arbitrary a, Eq a) => a -> a -> Bool) -> [IO ()]
forallRings2 x =
[ quickCheck (x :: Matrix -> Matrix -> Bool)
, quickCheck (x :: Integer -> Integer -> Bool)
, quickCheck (x :: Modulo -> Modulo -> Bool)
]
forallRings3 :: (forall a. (Ring a, Arbitrary a, Eq a) => a -> a -> a -> Bool) -> [IO ()]
forallRings3 x =
[ quickCheck (x :: Matrix -> Matrix -> Matrix -> Bool)
, quickCheck (x :: Integer -> Integer -> Integer -> Bool)
, quickCheck (x :: Modulo -> Modulo -> Modulo -> Bool)
]

ringTests :: IO ()
ringTests = sequence_ $
forallRings propAddId
++ forallRings prop_AddInv
++ forallRings prop_MulId
++ forallRings2 prop_AddCommutative
++ forallRings3 prop_AddAssociative
++ forallRings3 prop_MulAssociative
++ forallRings3 prop_Distributive

我对这个解决方案有些不满意。我发现 forAllRingsX 函数有点丑陋和重复。原因是我的测试有不同数量的参数。有没有更好的方法(即具有较少样板代码的方法)来测试所有实例?

最佳答案

我认为 typeclass 函数是这里的方法。一种简单的方法是向类 Ring 添加另一个成员。喜欢 ringTests :: (Eq a, Arbitrary a) => proxy a -> IO Result .代理参数将是必要的,以便调用者可以指定要测试的类型:ringTests (Proxy :: Proxy Matrix) .
ringTests可以有一个易于编写的默认实现;您可能需要 ScopedTypeVariables获取范围内的类型变量。

您当然也可以将测试函数放在一个单独的类中,同样使用默认实现。那么你只需要写 instance RingTests Matrix where等等,不需要实现。

关于haskell - 使用 Quickcheck 测试类型类,可变数量的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26468648/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com