我有一个从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)
首先,GHC抱怨说我使用类型的方式不是标准的haskell所以我必须使用一些编译器标志(这不是我想要的,因为我觉得必须有一个简单的解决方案没有标志的简单问题)。
其次,我的任意函数都有错误的类型,这很明显。但后来我真的没弄明白如何编写一个函数来返回一个三元组,其中包含1-6的随机Ints。
如果有人能帮助我,我将不胜感激。
谢谢。
答案 0 :(得分:5)
首先,已经有这两个实例:
instance Arbitrary Int
instance (Arbitrary a, Arbitrary b, Arbitrary c) =>
Arbitrary (a, b, c)
这意味着(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)
或许可以使用内置(Int,Int,Int)实例并使用(succ。(mod
6))对这三个元素进行后处理。