[英]Can I generate arbitrary strings, and avoid repeating specifications in QuickCheck?
Given 给定
data MyType = MyType ...
makeMyType :: String -> String -> String -> MyType
-- ...
type StringThing = String
where the strings that makeMyType
expects are (respectively): makeMyType
期望的字符串分别在哪里:
-
delimited string of some custom strings (eg, "Hilary-Jeb-David-Charles"
), -
一些自定义字符串的分隔字符串(例如, "Hilary-Jeb-David-Charles"
), .
.
delimited string of integers between 1 and 26, each padded with a zero to two characters (eg, "04.23.11.09"
) "04.23.11.09"
) I can use QuickCheck to generate adequate test cases with something like 我可以使用QuickCheck生成类似以下内容的足够的测试用例
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
import Test.QuickCheck
import Data.List (intercalate)
import Text.Printf (printf)
-- This really should be an arbitrary string of random length in some range
instance Arbitrary StringThing where
arbitrary = elements ["FUSHFJSHF","KLSJDHFLSKJDHFLSKJDFHLSKJDHFLSKJOIWURURW","GHSHDHUUUHHHA"]
instance Arbitrary MyType where
arbitrary = do
-- This repetition feels unnecessary
w1 <- elements ['A'..'Z']
w2 <- elements ['A'..'Z']
w3 <- elements ['A'..'Z']
w4 <- elements ['A'..'Z']
c1 <- elements someListOfCustomStuff
c2 <- elements someListOfCustomStuff
c3 <- elements someListOfCustomStuff
c4 <- elements someListOfCustomStuff
r1 <- choose (1,26)
r2 <- choose (1,26)
r3 <- choose (1,26)
r4 <- choose (1,26)
return $ makeMyType (intercalate "-" [c4,c3,c2,c1])
[w1,w2,w3,w4]
(intercalate "." $ (printf "%02d") <$> ([r1,r2,r3,r4] :: [Int]))
prop_SomeProp :: MyType -> StringThing -> Bool
prop_SomeProp mt st = ...
But StringThing
really should take on arbitrary strings of capital letters of random length within some range, and the repetition of the same specification for all the w...
s, c..
s, and r....
s seems unnecessary. 但
StringThing
确实应该采取一些范围内随机长度,和同规格的重复的大写字母的任意字符串的所有w...
S, c..
s和r....
小号似乎没有必要。
Is there a way in QuickCheck to: QuickCheck中有没有一种方法可以:
elements
or choose
among multiple values? elements
“共享”规范或在多个值中choose
? Yes. 是。 Haskell is great at being able to factor things out!
Haskell擅长将问题分解出来! You can certainly name and share subexpressions like
elements ['A'..'Z']
您当然可以命名和共享子表达式,例如
elements ['A'..'Z']
capitals = elements ['A'..'Z']
instance Arbitrary StringThing where
arbitrary = do
l <- choose (1,50) -- this is your string length
replicateM l capitals
And for your MyType, you can also use replicateM quite a lot: 对于MyType,还可以大量使用copyM:
instance Arbitrary MyType where
arbitrary = do
ws <- replicateM 4 capitals
cs <- replicateM 4 (elements someListOfCustomStuff)
rs <- replicateM 4 (choose (1,26))
return $ makeMyType (intercalate "-" cs)
ws
(intercalate "." $ (printf "%02d") <$> (rs :: [Int]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.