我有一个简单的类型定义:如何生成一个简单类型的任意实例进行快速检查
data Cell = Cell {
x :: Int,
y :: Int
} deriving (Show)
我不能使用Cell
作为输入到一个快速检查属性,大概是因为快速检查不知道如何生成单元格值。
我的理解是我需要让Cell成为Arbitrary
typeclass的一个实例。
我该怎么做,例如,如果我希望Cell对于x和y具有随机正值而生成?
我有一个简单的类型定义:如何生成一个简单类型的任意实例进行快速检查
data Cell = Cell {
x :: Int,
y :: Int
} deriving (Show)
我不能使用Cell
作为输入到一个快速检查属性,大概是因为快速检查不知道如何生成单元格值。
我的理解是我需要让Cell成为Arbitrary
typeclass的一个实例。
我该怎么做,例如,如果我希望Cell对于x和y具有随机正值而生成?
为您的数据类型编写实例Arbitrary
很容易。您只需执行arbitrary
函数,该函数应返回Gen Cell
。要做到这一点最简单的方法是利用现有Arbitrary
实例,并指出Gen
是一个单子,所以我们可以使用do
-notation:
instance Arbitrary Cell where
arbitrary = do
Positive x <- arbitrary
Positive y <- arbitrary
return $ Cell x y
另外,发电机经常可以文笔优美从Control.Applicative
使用运营商:
instance Arbitrary Cell where
arbitrary = Cell <$> pos <*> pos
where pos = getPositive <$> arbitrary -- getPositive requires QC >= 2.5
这里,我还利用从Test.QuickCheck.Modifiers的Positive
修改,以确保我们生成的正整数。
要编写更复杂的发电机,请查看Test.QuickCheck.Gen的各种发电机。
您可以生成一个Arbitrary
实例做使用TemplateHaskell和derive包相同:
import Data.DeriveTH
derive makeArbitrary ''Cell
您应该提及Data.DeriveTH来自哪里。 – 2013-05-16 10:11:59
这是我真的* *喜欢使用应用型的语法来代替。 – 2013-05-08 15:55:24
另外,请考虑编写'shrink'的实现。也许这不太重要,但为某些情况节省了很多努力。 – 2013-05-16 10:13:00