如何为快速检查生成简单类型的任意实例

lia*_*nan 37 haskell quickcheck

我有一个简单的类型定义:

data Cell = Cell {
    x       :: Int,
    y       :: Int
  } deriving (Show)
Run Code Online (Sandbox Code Playgroud)

我不能Cell用作quickcheck属性的输入,大概是因为quickcheck不知道如何生成Cell值.

我的理解是我需要让Cell成为Arbitrary类型类的一个实例.

我该怎么做,例如,如果我想用x和y的随机正值生成Cell?

ham*_*mar 49

Arbitrary为您的数据类型编写实例很容易.你只需要实现该arbitrary函数,该函数应该返回一个Gen Cell.最简单的方法是使用现有Arbitrary实例并注意这Gen是一个monad,所以我们可以使用do-notation:

instance Arbitrary Cell where
   arbitrary = do
     Positive x <- arbitrary
     Positive y <- arbitrary
     return $ Cell x y
Run Code Online (Sandbox Code Playgroud)

或者,通常可以使用以下运算符优雅地编写生成器Control.Applicative:

instance Arbitrary Cell where
   arbitrary = Cell <$> pos <*> pos
     where pos = getPositive <$> arbitrary  -- getPositive requires QC >= 2.5
Run Code Online (Sandbox Code Playgroud)

在这里,我还使用了Test.QuickCheck.Modifiers中的Positive修饰符来确保我们只生成正整数.

要编写更复杂的生成器,请查看Test.QuickCheck.Gen中的各种生成器.

  • 这是我真的*喜欢使用Applicative语法的地方. (3认同)
  • 另外,请考虑为`shrink`编写实现.也许在这里不太重要,但在某些情况下可以节省很多精力. (3认同)

Kot*_*lar 18

您可以Arbitrary使用TemplateHaskell 生成一个实例并派生包:

import Data.DeriveTH

derive makeArbitrary ''Cell
Run Code Online (Sandbox Code Playgroud)

  • 您应该提到Data.DeriveTH的来源. (5认同)