2013-05-08 24 views
33

我有一个简单的类型定义:如何生成一个简单类型的任意实例进行快速检查

data Cell = Cell { 
    x  :: Int, 
    y  :: Int 
    } deriving (Show) 

我不能使用Cell作为输入到一个快速检查属性,大概是因为快速检查不知道如何生成单元格值。

我的理解是我需要让Cell成为Arbitrary typeclass的一个实例。

我该怎么做,例如,如果我希望Cell对于x和y具有随机正值而生成?

回答

45

为您的数据类型编写实例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.ModifiersPositive修改,以确保我们生成的正整数。

要编写更复杂的发电机,请查看Test.QuickCheck.Gen的各种发电机。

+2

这是我真的* *喜欢使用应用型的语法来代替。 – 2013-05-08 15:55:24

+3

另外,请考虑编写'shrink'的实现。也许这不太重要,但为某些情况节省了很多努力。 – 2013-05-16 10:13:00

15

您可以生成一个Arbitrary实例做使用TemplateHaskell和derive包相同:

import Data.DeriveTH 

derive makeArbitrary ''Cell 
+5

您应该提及Data.DeriveTH来自哪里。 – 2013-05-16 10:11:59

相关问题