0

我有一个从 Network.HTTP 获取 ResponseCode 的函数。为了使用 QuickCheck 对其进行测试,我想为 ResponseCode 编写一个 Arbitrary 实例。(如果您不知道,ResponseCode 只是该库中的三个整数:type ResponseCode = (Int, Int, Int))。

所以我写了这样的东西:

instance Arbitrary ResponseCode where
    arbitrary = triple ( elements [1..6] )
       where triple f = (f, f, f)

首先,GHC 抱怨我使用类型的方式不是标准的 haskell,所以我必须使用一些编译器标志(这不是我真正想要的,因为我觉得必须有一个简单的解决方案来解决这个简单的问题,而无需标志)。

其次,我的任意函数类型错误,这很明显。但是后来我真的不知道如何编写一个函数来返回一个三元组,其中随机整数范围为 1-6。

如果有人可以在这里帮助我,我将不胜感激。

谢谢你。

4

1 回答 1

5

首先,已经有这两个实例:

instance Arbitrary Int
instance (Arbitrary a, Arbitrary b, Arbitrary c) =>
         Arbitrary (a, b, c)

这意味着 (Int,Int,Int) 已经是 Arbitrary 的一个实例。这意味着类型同义词 ResponseCode 已经是一个实例。您不能定义和使用第二个实例。

您可以尝试使用 Test.QuickCheck.Gen.suchThat 但我假设在这种情况下它不会很好地工作。如果可以的话,我建议使用新类型包装器:

import Test.QuickCheck
import Network.HTTP.Base
import Control.Applicative
import System.Random

newtype Arb'ResponseCode = Arb'ResponseCode { arb'ResponseCode :: ResponseCode }
  deriving (Show)

instance Arbitrary Arb'ResponseCode where
  arbitrary = do
      responseCode <- (,,) <$> f <*> f <*> f
      return (Arb'ResponseCode responseCode)
    where f = elements [1..6]

-- To use this you can call
-- (fmap arb'ResponseCode arbitrary)
-- instead of just (arbitrary)

或者也许使用内置的 (Int,Int,Int) 实例并使用 (succ . ( mod6)) 对这三个元素进行后处理。

于 2012-04-27T06:42:50.640 回答