当我们喜欢时
此刻,我正在生成这样的字符串:
arbStr :: Gen String
arbStr = listOf $ elements (alpha ++ digits)
where alpha = ['a'..'z']
digits = ['0'..'9']
但是很明显,这只能从字母数字字符生成字符串。我怎么做才能从所有可能的字符中生成?
Char
是Enum
和Bounded
类型类的实例,可以使用arbitraryBoundedEnum :: (Bounded a, Enum a) => Gen a
函数:
arbitraryBoundedEnum :: (Bounded a, Enum a) => Gen a
例如:
import Test.QuickCheck(Gen, arbitraryBoundedEnum, listOf)
arbStr :: Gen String
arbStr = listOf arbitraryBoundedEnum
或者您可以在Prelude Test.QuickCheck> sample arbStr
""
""
"\821749"
"\433465\930384\375110\256215\894544"
"\431263\866378\313505\1069229\238290\882442"
""
"\126116\518750\861881\340014\42369\89768\1017349\590547\331782\974313\582098"
"\426281"
"\799929\592960\724287\1032975\364929\721969\560296\994687\762805\1070924\537634\492995\1079045\1079821"
"\496024\32639\969438\322614\332989\512797\447233\655608\278184\590725\102710\925060\74864\854859\312624\1087010\12444\251595"
"\682370\1089979\391815"
类型类中使用arbitrary
:
Arbitrary Char
注意,import Test.QuickCheck(Gen, arbitrary, listOf)
arbStr :: Gen String
arbStr = listOf arbitrary
的arbitrary
实现为使得ASCII字符比非ASCII字符普遍(三倍),因此“分布”不同。
由于Char是Bounded以及Enum的一个实例(通过向GHCI询问Char
来确认这一点,因此您可以简单地编写]]
:i Char
获取所有合法字符的列表。显然,这不会导致有效的随机访问!因此,您可以改为使用
[minBound..maxBound] :: [Char]
将边界转换为Int
,并使用QuickCheck的功能从整数范围中进行选择,然后使用Data.Char.ord :: Char -> Int
映射回字符。
当我们喜欢时
Data.Chra.chr :: Int -> Char
我们得到所有字符的数量并说哇..!如果您认为列表太大,则可以总是喜欢λ> length ([minBound..maxBound] :: [Char])
1114112
来限制范围。
因此,如果您需要drop x . take y
许多随机字符,只需n
列表,然后从经过改组的列表中进行shuffle :: [a] -> IO [a]
。
编辑:
当然,由于改组可能会很昂贵,因此,最好选择明智的策略。 randomly限制所有字符列表是理想的。就是
制作shuffle :: [a] -> IO [a]
take n
最后从[[Item 2
的结果中抽取limits = liftM sort . mapM randomRIO $ replicate 2 (0,1114112) :: (Ord a, Random a, Num a) => IO [a]
像随机的limits >>= \[min,max] -> return . drop min . take max $ ([minBound..maxBound] :: [Char])
一样,例如n
。当我们喜欢时