带有动态元素集的 QuickCheck
QuickCheck with Dynamic Element Sets
有没有办法以编程方式控制在任意定义内的元素调用中使用的值集?我希望能够生成一个任意变量引用作为随机表达式的一部分,但是可供选择的变量标识符集应该是可配置的。
例如,假设以下数据类型:
data Expr = Num Int
| Var String
| BinOp Op Expr Expr
data Op = Add | Sub | Mul | Div deriving (Eq, Ord, Enum)
然后我想为这种类型定义一个任意实例,看起来像这样:
instance Arbitrary Op where
arbitrary = elements [Add .. ]
instance Arbitrary Expr where
arbitrary = oneof [ fmap Num arbitrary
, arbitraryBinOp
, fmap Var (elements varNames)
]
arbitraryBinOp = do (op, e0, e1) <- arbitrary
return (BinOp op e0 e1)
现在棘手的是 "varNames" 部分。从概念上讲,我希望能够做这样的事情:
do args <- getArgs
tests <- generate $ vectorOf 10 ((arbitrary args)::Gen Expr)
但显然我无法通过任意调用向下传播该 args-vector,因为 "arbitrary" 不接受这样的参数...
当生成器不需要任何上下文时,Arbitrary
实际上只是一种便利。如果您需要参数化您的生成器,您可以将它们定义为常规函数,并且 QuickCheck 具有组合器来使用此类显式生成器而不是 Arbitrary
个实例。
genExpr :: [String] -> Gen Expr
genExpr varNames =
oneof [ fmap Num arbitrary
, arbitraryBinOp
, fmap Var (elements varNames)
]
main :: IO ()
main = do
args <- getArgs
tests <- generate $ vectorOf 10 (genExpr args)
{- do stuff -}
return ()
有没有办法以编程方式控制在任意定义内的元素调用中使用的值集?我希望能够生成一个任意变量引用作为随机表达式的一部分,但是可供选择的变量标识符集应该是可配置的。
例如,假设以下数据类型:
data Expr = Num Int
| Var String
| BinOp Op Expr Expr
data Op = Add | Sub | Mul | Div deriving (Eq, Ord, Enum)
然后我想为这种类型定义一个任意实例,看起来像这样:
instance Arbitrary Op where
arbitrary = elements [Add .. ]
instance Arbitrary Expr where
arbitrary = oneof [ fmap Num arbitrary
, arbitraryBinOp
, fmap Var (elements varNames)
]
arbitraryBinOp = do (op, e0, e1) <- arbitrary
return (BinOp op e0 e1)
现在棘手的是 "varNames" 部分。从概念上讲,我希望能够做这样的事情:
do args <- getArgs
tests <- generate $ vectorOf 10 ((arbitrary args)::Gen Expr)
但显然我无法通过任意调用向下传播该 args-vector,因为 "arbitrary" 不接受这样的参数...
Arbitrary
实际上只是一种便利。如果您需要参数化您的生成器,您可以将它们定义为常规函数,并且 QuickCheck 具有组合器来使用此类显式生成器而不是 Arbitrary
个实例。
genExpr :: [String] -> Gen Expr
genExpr varNames =
oneof [ fmap Num arbitrary
, arbitraryBinOp
, fmap Var (elements varNames)
]
main :: IO ()
main = do
args <- getArgs
tests <- generate $ vectorOf 10 (genExpr args)
{- do stuff -}
return ()