给出
data MyType = MyType ...
makeMyType :: String -> String -> String -> MyType
-- ...
type StringThing = String
makeMyType
期望的字符串(分别):
-
一些自定义字符串的分隔字符串(例如"Hilary-Jeb-David-Charles"
),.
分隔的1到26之间的整数字符串,每个字符用0到2个字符填充(例如"04.23.11.09"
)我可以使用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 = ...
但是StringThing
确实应该在某个范围内采用随机长度的任意大写字母串,并且对所有w...
s,c..
s重复相同的规范,以及r....
似乎没必要。
QuickCheck中有没有办法:
elements
或choose
“共享”规范?答案 0 :(得分:4)
是。 Haskell非常善于将事情分解出来!您当然可以命名和共享子表达式,例如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
对于你的MyType,你也可以使用replicateM:
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]))