我正试图找出如何结合使用基于smallcheck属性的测试库。
我遇到了多字段记录类型的问题:如何使用Serial类型的mor超过4个字段成员来创建记录类型?
我认为这是正常的做法:
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
import Test.Tasty
import Test.Tasty.SmallCheck
import Test.SmallCheck.Series
data T1 = T1 { p1 :: Int,
p2 :: Char,
p3 :: [Int]
} deriving (Show, Eq)
instance (Monad m) => Serial m T1 where
series = cons3 T1
main :: IO ()
main = defaultMain tests
tests :: TestTree
tests = testGroup "Tests" [scProps]
scProps = testGroup "(checked by SmallCheck)"
[ testProperty "Test1" prop_test1
]
prop_test1 x y = x == y
where types = (x :: T1, y :: T1)这是可行的,当然'Test1‘失败了。但是,这种方法不适用于超过4个字段的记录类型,因为consN函数仅定义为最多接受4个参数。下面是声明函数的模块链接的Test.SmallCheck.Series。
例如:
data T1 = T1 { p1 :: Int,
p2 :: Char,
p3 :: Int,
p4 :: Int,
p5 :: [Int]
} deriving (Show, Eq)将它添加到Serial的方法是什么?我试过像这样使用泛型:
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
{-# LANGUAGE DeriveGeneric #-}
import Test.Tasty
import Test.Tasty.SmallCheck
import Test.SmallCheck.Series
import GHC.Generics
data T1 = T1 { p1 :: Int,
p2 :: Char,
p3 :: [Int]
} deriving (Show, Generic)
instance Serial m a => Serial m T1但ghc拒绝接受上述示例,并提供以下信息:
Variable occurs more often in a constraint than in the instance head
in the constraint: Serial m a
(Use -XUndecidableInstances to permit this)
In the instance declaration for `Serial m T1'事先非常感谢!
jules
发布于 2013-12-14 09:37:14
例如,cons3是如何在SmallCheck中定义的:
cons3 :: (Serial m a, Serial m b, Serial m c) =>
(a->b->c->d) -> Series m d
cons3 f = decDepth $
f <$> series
<~> series
<~> series因此,通过类推,下面是如何用任意数量的字段定义类型的实例:
instance Monad m => Serial m T1 where
series = decDepth $
T1 <$> series <~> series <~> series <~> series <~> series(上述定义中的每个series都对应于数据结构的一个字段)。
关于泛型代码,应该如下所示:
instance Monad m => Serial m T1这里没有a,所以您的约束是多余的(实际上会导致问题)。
https://stackoverflow.com/questions/20581177
复制相似问题