使用Arbitrary实例生成三元组(Network.HTTP.ResponseCode)

ret*_*hab 0 haskell quickcheck

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

所以我写了这样的东西:

instance Arbitrary ResponseCode where
    arbitrary = triple ( elements [1..6] )
       where triple f = (f, f, f)
Run Code Online (Sandbox Code Playgroud)

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

其次,我的任意函数都有错误的类型,这很明显.但后来我真的不知道如何编写一个函数,返回一个三元组,随机的Ints从1-6开始.

如果有人能帮助我,我将不胜感激.

谢谢.

Chr*_*icz 5

首先,这两个实例已经存在:

instance Arbitrary Int
instance (Arbitrary a, Arbitrary b, Arbitrary c) =>
         Arbitrary (a, b, c)
Run Code Online (Sandbox Code Playgroud)

这意味着(Int,Int,Int)已经是任意的实例.这意味着类型同义词ResponseCode已经是一个实例.您无法定义和使用第二个实例.

您可以尝试使用Test.QuickCheck.Gen.such但我假设它在这种情况下不能很好地工作.如果可以,我建议使用newtype包装器:

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)
Run Code Online (Sandbox Code Playgroud)

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