Given
data MyType = MyType ...
makeMyType :: String -> String -> String -> MyType
-- ...
type StringThing = String
where the strings that makeMyType
expects are (respectively):
- a
-
delimited string of some custom strings (e.g.,"Hilary-Jeb-David-Charles"
), - a string of 4 capital letters, and
- a
.
delimited string of integers between 1 and 26, each padded with a zero to two characters (e.g.,"04.23.11.09"
)
I can use QuickCheck to generate adequate test cases with something like
{-# 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.
Is there a way in QuickCheck to:
- generate random strings with length within some bounds, restricted to certain characters, and
- "share" a specification using
elements
orchoose
among multiple values?